<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xml:lang="en-us">
  <channel>
		<title>Posts on Seirdy’s Home</title>
    <link>https://envs.net/~seirdy/posts/</link>
    <description>Recent content in Articles on Seirdy’s Home</description>
		<ttl>1440</ttl>
		<sy:updatePeriod>daily</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>seirdy@seirdy.one (Seirdy)</managingEditor>
    <webMaster>seirdy@seirdy.one (Seirdy)</webMaster>
    
		<atom:link href="https://envs.net/~seirdy/posts/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item><title>Post-OCSP certificate revocation in the Web PKI</title>
      <link>https://envs.net/~seirdy/posts/2024/09/25/post-ocsp-revocation/</link>
      <pubDate>Wed, 25 Sep 2024 15:29:38 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2024/09/25/post-ocsp-revocation/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2024/09/25/post-ocsp-revocation/">&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Today, &lt;abbr title=&#34;Transport Layer Security&#34;&gt;TLS&lt;/abbr&gt; certificates in the Web public key infrastructure (&lt;abbr&gt;PKI&lt;/abbr&gt;) have long validity: almost all remain valid for at least &lt;em&gt;three months!&lt;/em&gt; An attacker compromising a certificate early enough in its lifetime&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; keeps it compromised for months. Certificate revocation addresses this problem: a client must know to distrust a certain key for a domain, even if the valid key hasn&amp;rsquo;t expired yet.&lt;/p&gt;
&lt;p&gt;The issue? Billions of clients use the Web &lt;abbr&gt;PKI&lt;/abbr&gt;: browsers, crawlers, link-preview generators, chatbots, email servers, email clients, etc. The easy part for a &lt;abbr&gt;CA&lt;/abbr&gt; is knowing when to revoke a certificate.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; The hard part is telling every client to ignore a certain compromised certificate. All approaches to revocation trace their roots to at least one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Certificate Revocation Lists (&lt;abbr&gt;CRLs&lt;/abbr&gt;)&lt;/li&gt;
&lt;li&gt;Online Certificate Status Protocol (&lt;abbr&gt;OCSP&lt;/abbr&gt;)&lt;/li&gt;
&lt;li&gt;Short-lived certificates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Initial approaches to each option showed major shortcomings. All three evolved:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;abbr&gt;CRLs&lt;/abbr&gt; became sharded &lt;abbr&gt;CRLs&lt;/abbr&gt; and combined client-side &amp;ldquo;summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; became &lt;abbr&gt;OCSP&lt;/abbr&gt; stapling and &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple. It almost evolved into &lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple. The shutdown of &lt;abbr&gt;OCSP&lt;/abbr&gt; resolvers impacts all three; we need alternatives.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Short-lived certificates became &lt;abbr&gt;ACME-STAR&lt;/abbr&gt; and delegated credentials.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;ll break down each of these, along with some of my proposals. We should double down on client-side summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and work towards reducing certificate lifetimes.&lt;/p&gt;
&lt;p&gt;Most solutions still have caveats or won&amp;rsquo;t gain mainstream adoption for several years. Until then, I propose offering six-week certificates.&lt;/p&gt;
&lt;h3 id=&#34;motivation&#34;&gt;Motivation&lt;/h3&gt;
&lt;p&gt;Why discuss revocation now?&lt;/p&gt;
&lt;p&gt;In August 2023, the &lt;abbr title=&#34;Certificate Authority&#34;&gt;CA&lt;/abbr&gt;/Browser Forum voted in favor of &lt;a href=&#34;https://cabforum.org/2023/07/14/ballot-sc-063-v4-make-ocsp-optional-require-crls-and-incentivize-automation/&#34;&gt;Ballot SC-064 v4&lt;/a&gt;. This ballot made the Online Certificate Status Protocol (&lt;abbr title=&#34;Online Certificate Status Protocol&#34;&gt;OCSP&lt;/abbr&gt;) optional and outlined where &lt;abbr&gt;CAs&lt;/abbr&gt; should focus instead. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span&gt;Let&amp;rsquo;s Encrypt&lt;/span&gt; published &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://letsencrypt.org/2024/07/23/replacing-ocsp-with-crls.html&#34;&gt;Intent to End &lt;abbr&gt;OCSP&lt;/abbr&gt; Service&lt;/a&gt;&lt;/cite&gt; on &lt;time class=&#34;dt-published published&#34;&gt;2024-07-23&lt;/time&gt;&lt;/span&gt;, and will likely shut down its &lt;abbr&gt;OCSP&lt;/abbr&gt; service sometime in late 2025 or 2026. Let&amp;rsquo;s Encrypt issues &lt;abbr title=&#34;Transport Layer Security&#34;&gt;TLS&lt;/abbr&gt; certificates for almost 60% of websites.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; This means most websites will soon have no more &lt;abbr&gt;OCSP&lt;/abbr&gt;: while it might live on in other networks, &lt;abbr&gt;OCSP&lt;/abbr&gt; will leave the Web &lt;abbr&gt;PKI&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;The announcement from Let&amp;rsquo;s Encrypt merely declares intent. Some staff members show openness to a migration period for stapling, with at least a year before any changes.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; After the migration period, I expect webmasters to lose the option for &lt;abbr&gt;OCSP&lt;/abbr&gt; Stapling or working &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple. Without &lt;abbr&gt;OCSP&lt;/abbr&gt;, most clients either trust all certificates from their issuance until expiry or have to constantly update compressed revocation filters (&amp;ldquo;summarized &lt;abbr title=&#34;Certificate Revocation Lists&#34;&gt;CRLs&lt;/abbr&gt;&amp;rdquo;) to check the revocation status of a certificate. We can also look to other solutions on the horizon.&lt;/p&gt;
&lt;p&gt;Note: I made this article &lt;abbr title=&#34;Automatic Certificate Management Environment&#34;&gt;ACME&lt;/abbr&gt;-centric.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; Most websites use &lt;abbr&gt;ACME&lt;/abbr&gt; to automate the generation and renewal of certificates validated by a certificate authority (&lt;abbr&gt;CA&lt;/abbr&gt;). Where non-&lt;abbr&gt;ACME&lt;/abbr&gt; setups are relevant, I disregard them. Use &lt;abbr&gt;ACME&lt;/abbr&gt;!&lt;/p&gt;
&lt;h3 id=&#34;target-audience&#34;&gt;Target audience&lt;/h3&gt;
&lt;p&gt;I wrote this for people with some basic familiarity with &lt;abbr&gt;TLS&lt;/abbr&gt;, certificate authorities, and maybe &lt;abbr&gt;OCSP&lt;/abbr&gt;; this represents what I knew before I started writing this article. I did my best to link other resources and define terms where appropriate.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; The &lt;a href=&#34;https://letsencrypt.org/docs/glossary/&#34;&gt;Let&amp;rsquo;s Encrypt glossary&lt;/a&gt; might assist you.&lt;/p&gt;
&lt;p&gt;For readers less familiar, I recommend &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://carrickbartle.com/certificates.html&#34;&gt;Intro to &lt;abbr&gt;TLS&lt;/abbr&gt; certificates&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://carrickbartle.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Carrie&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Bartle&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; for a primer on how &lt;abbr&gt;TLS&lt;/abbr&gt; certificates and Web &lt;abbr&gt;PKI&lt;/abbr&gt; work.&lt;/p&gt;
&lt;hr /&gt;
&lt;section
	aria-label=&#34;comic, caption, and transcript&#34;
	
	id=&#34;xkcd-2501&#34; tabindex=&#34;-1&#34;&gt;
&lt;h4 id=&#34;average-familiarity&#34;&gt;&lt;span&gt;xkcd comic: Average Familiarity&lt;/span&gt;&lt;/h4&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_2501_dark.1887286888.webp&#34;
type=&#34;image/webp&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_2501_dark.2982982248.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_2501.1392629356.webp&#34;
type=&#34;image/webp&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_2501.1461086589.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;295&#34; height=&#34;480&#34;
src=&#34;https://envs.net/~seirdy/p/xkcd_2501.1461086589.png&#34; alt=&#34;Comic: two stick figures talking to each other. Transcript follows.&#34;
aria-describedby=&#34;transcript-xkcd-2501&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;I&amp;rsquo;m not an &amp;ldquo;expert&amp;rdquo; but this comic captures how the first draft of this article read. From &lt;a href=&#34;https://xkcd.com/1309&#34;&gt;xkcd&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
 &lt;details&gt;
&lt;summary&gt;Toggle comic &lt;span&gt;transcript&lt;/span&gt;&lt;/summary&gt;
&lt;section id=&#34;transcript-xkcd-2501&#34;&gt;
&lt;h5&gt;Comic transcript&lt;/h5&gt;
	&lt;div&gt;
		&lt;p&gt;Ponytail and Cueball are talking. Ponytail has her hand raised, palm up, towards Cueball.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Ponytail&lt;/dt&gt;
&lt;dd&gt;Silicate chemistry is second nature to us geochemists, so it&amp;rsquo;s easy to forget that the average person only knows the formulas for olivine and one or two feldspars.&lt;/dd&gt;
&lt;dt&gt;Cueball&lt;/dt&gt;
&lt;dd&gt;And quartz, of course.&lt;/dd&gt;
&lt;dt&gt;Ponytail&lt;/dt&gt;
&lt;dd&gt;Of course.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;A caption below the panel reads, &lt;q&gt;Even when they&amp;rsquo;re trying to compensate for it, experts in anything wildly overestimate the average person&amp;rsquo;s familiarity with their field.&lt;/q&gt;&lt;/p&gt;
&lt;p role=&#34;doc-credit&#34;&gt;Transcript from the &lt;a href=&#34;https://explainxkcd.com/wiki/index.php/2501:_Average_Familiarity#Transcript&#34;&gt;explain xkcd wiki entry for xkcd #2501&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/details&gt;

&lt;/section&gt;
&lt;hr /&gt;

&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#introduction&#34;&gt;Introduction&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#motivation&#34;&gt;Motivation&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#target-audience&#34;&gt;Target audience&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#certificate-revocation-lists&#34;&gt;Certificate Revocation Lists&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#online-certificate-status-protocol-abbrocspabbr&#34;&gt;Online Certificate Status Protocol (&lt;abbr&gt;OCSP&lt;/abbr&gt;)&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#abbrocspabbr-stapling-and-must-staple&#34;&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Stapling and Must-Staple&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#abbrocspabbr-expect-staple&#34;&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#poor-implementations&#34;&gt;Poor implementations&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#querying-abbrcrlabbr-shards&#34;&gt;Querying &lt;abbr&gt;CRL&lt;/abbr&gt; shards&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#client-side-summarized-abbrcrlsabbr&#34;&gt;Client-side summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#googles-approach-crlsets&#34;&gt;Google&amp;rsquo;s approach: CRLSets&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#mozillas-approach-crlite&#34;&gt;Mozilla&amp;rsquo;s approach: CRLite&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#apples-approach-validapplecom&#34;&gt;Apple&amp;rsquo;s approach: valid.apple.com&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#shortcomings-of-summarized-abbrcrlsabbr&#34;&gt;Shortcomings of summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#lets-revoke&#34;&gt;Let&amp;rsquo;s Revoke&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#abbracmeabbr-renewal-information-abbrariabbr&#34;&gt;&lt;abbr&gt;ACME&lt;/abbr&gt; Renewal Information (&lt;abbr&gt;ARI&lt;/abbr&gt;)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#short-lived-certificates&#34;&gt;Short-lived certificates&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#abbracme-starabbr&#34;&gt;&lt;abbr&gt;ACME-STAR&lt;/abbr&gt;&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#delegated-credentials&#34;&gt;Delegated credentials&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#abbracme-starabbr-delegation&#34;&gt;&lt;abbr&gt;ACME-STAR&lt;/abbr&gt; Delegation&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#own-proposals&#34;&gt;My proposals&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#no-spof&#34;&gt;Eliminating single points of failure&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#enforcing-stc&#34;&gt;Enforcing short-term certificates&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#incremental-change-shorter-long-lived-certificates&#34;&gt;Incremental change: shorter long-lived certificates&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#requesting-a-shorter-lifetime&#34;&gt;Requesting a shorter lifetime&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#conclusion&#34;&gt;Conclusion&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#aside-browser-wars&#34;&gt;Aside: browser wars&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;h2 id=&#34;certificate-revocation-lists&#34;&gt;Certificate Revocation Lists&lt;/h2&gt;
&lt;p&gt;&lt;abbr title=&#34;Certificate Authorities&#34;&gt;CAs&lt;/abbr&gt; regularly publish live lists of revoked certificates called &lt;dfn&gt;Certificate Revocation Lists (&lt;abbr&gt;CRLs&lt;/abbr&gt;)&lt;/dfn&gt;. When revoking a certificate, &lt;abbr&gt;CAs&lt;/abbr&gt; update &lt;abbr&gt;OCSP&lt;/abbr&gt; responses and push an entry to a &lt;abbr title=&#34;Certificate Revocation List&#34;&gt;CRL&lt;/abbr&gt;. They have up to a seven-day deadline to do so (less in certain cases&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;). &lt;abbr&gt;CAs&lt;/abbr&gt; annotate entries with one of ten possible reasons for revocation. See &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.rfc-editor.org/rfc/rfc5280.html&#34;&gt;&lt;abbr title=&#34;Request for Comments&#34;&gt;RFC&lt;/abbr&gt; 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (&lt;abbr&gt;CRL&lt;/abbr&gt;) Profile&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; for details on the contents of &lt;abbr&gt;CRLs&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;&lt;abbr&gt;CRLs&amp;rsquo;&lt;/abbr&gt; large size and short validity make them a poor fit for client-side revocation checking: most clients can&amp;rsquo;t regularly re-download such large lists for revocation lookups. &lt;abbr&gt;CAs&lt;/abbr&gt; started offering &lt;abbr&gt;OCSP&lt;/abbr&gt; as a lightweight alternative. &lt;abbr&gt;CRLs&lt;/abbr&gt; are far from obsolete, though: they support transparency, research, and other revocation technologies.&lt;/p&gt;
&lt;p&gt;&lt;abbr&gt;CRLs&lt;/abbr&gt;, the oldest revocation method in this article, only recently joined the &lt;abbr&gt;CA&lt;/abbr&gt;/Browser Baseline Requirements in Ballot SC-064 (the ballot I mentioned in &lt;a href=&#34;#motivation&#34;&gt;the &amp;ldquo;motivation&amp;rdquo; section&lt;/a&gt;).&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;online-certificate-status-protocol-abbrocspabbr&#34;&gt;Online Certificate Status Protocol (&lt;abbr&gt;OCSP&lt;/abbr&gt;)&lt;/h2&gt;
&lt;p&gt;Before trusting a certificate, browsers can ask its issuing &lt;abbr title=&#34;Certificate Authority&#34;&gt;CA&lt;/abbr&gt; if the &lt;abbr&gt;CA&lt;/abbr&gt; has revoked the certificate by using the Online Certificate Status Protocol (&lt;abbr&gt;OCSP&lt;/abbr&gt;). &lt;abbr&gt;OCSP&lt;/abbr&gt; has a host of problems:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Performance&lt;/dt&gt;
&lt;dd&gt;Asking a &lt;abbr&gt;CA&lt;/abbr&gt; about a new certificate before trusting it and loading a page can take hundreds of milliseconds or even seconds. That slows down page loads.&lt;/dd&gt;
&lt;dt&gt;Privacy&lt;/dt&gt;
&lt;dd&gt;This leaks domain names to the &lt;abbr&gt;CAs&lt;/abbr&gt; in question. Users can always switch their DNS providers to options they trust, but they can&amp;rsquo;t select a different place to check for &lt;abbr&gt;OCSP&lt;/abbr&gt; status.&lt;/dd&gt;
&lt;dt&gt;&lt;abbr&gt;CA&lt;/abbr&gt; reliability&lt;/dt&gt;
&lt;dd&gt;A &lt;abbr&gt;CA&lt;/abbr&gt; needs good uptime and needs to respond to a massive number of requests from HTTPS clients worldwide. &lt;abbr&gt;OCSP&lt;/abbr&gt;-supporting clients query every certificate from the &lt;abbr&gt;CA&lt;/abbr&gt; they encounter and expect a low-latency response.&lt;/dd&gt;
&lt;dt&gt;Robustness&lt;/dt&gt;
&lt;dd&gt;A bad firewall or a poor connection could prevent successful and timely connections to the &lt;abbr&gt;CA&lt;/abbr&gt; for an &lt;abbr&gt;OCSP&lt;/abbr&gt; check. For this reason, &lt;strong&gt;failed live &lt;abbr&gt;OCSP&lt;/abbr&gt; checks typically soft-fail.&lt;/strong&gt; If the &lt;abbr&gt;OCSP&lt;/abbr&gt; check doesn&amp;rsquo;t succeed or takes too long, the client trusts the certificate. An attacker can also block connections to the &lt;abbr&gt;CA&lt;/abbr&gt; to get a victim to trust a compromised certificate.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;abbrocspabbr-stapling-and-must-staple&#34;&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Stapling and Must-Staple&lt;/h3&gt;
&lt;p&gt;&lt;dfn&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Stapling&lt;/dfn&gt; addresses performance, privacy, and &lt;abbr&gt;CA&lt;/abbr&gt; reliability with a certificate extension. A web server can run an &lt;abbr&gt;OCSP&lt;/abbr&gt; check on its own certificates and attach the successful responses to them, refreshing them periodically. Clients receiving a fresh signed &lt;abbr&gt;OCSP&lt;/abbr&gt; response with a certificate need not fetch a copy themselves. It does slightly increase the size of a certificate, but the size increases pale in comparison to the footprint of live &lt;abbr&gt;OCSP&lt;/abbr&gt; lookups.&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;dfn&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple&lt;/dfn&gt; addresses &lt;abbr&gt;OCSP&amp;rsquo;s&lt;/abbr&gt; robustness concerns. A certificate can include metadata instructing clients to reject the certificate if it doesn&amp;rsquo;t include a successful stapled &lt;abbr&gt;OCSP&lt;/abbr&gt; response. With &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple, certificates behave almost as if they have a short one-week lifetime.&lt;/p&gt;
&lt;p&gt;Must-Staple has limited adoption: fewer than 1% of all unexpired &lt;abbr title=&#34;Transport Layer Security&#34;&gt;TLS&lt;/abbr&gt; certificates use this feature.&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; Any failure in the &lt;abbr&gt;OCSP&lt;/abbr&gt; pipeline means downtime. This risk prevents most &lt;abbr&gt;ACME&lt;/abbr&gt; clients from making it the default setting. Most webmasters won&amp;rsquo;t find the benefits worth the cost of adoption and the risks involved. See &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://blog.mozilla.org/security/2015/11/23/improving-revocation-ocsp-must-staple-and-short-lived-certificates/&#34;&gt;Improving Revocation: &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple and Short-lived Certificates&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://mastodon.social/@computerist&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Mark&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Goodwin&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, published on &lt;time class=&#34;dt-published published&#34;&gt;2015-11-23&lt;/time&gt;&lt;/span&gt; for Mozilla&amp;rsquo;s rationale.&lt;/p&gt;
&lt;h3 id=&#34;abbrocspabbr-expect-staple&#34;&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple&lt;/h3&gt;
&lt;p&gt;The &lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple proposal gained some adoption from a limited number of websites and received some browser-side experimentation but never took off. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://scotthelme.co.uk/ocsp-expect-staple/&#34;&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://scotthelme.co.uk/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Scott&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Helme&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; introduces the concept.&lt;/p&gt;
&lt;p&gt;The design of &lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple resembles HTTP Strict Transport Security (&lt;abbr&gt;HSTS&lt;/abbr&gt;), so let&amp;rsquo;s examine &lt;abbr&gt;HSTS&lt;/abbr&gt; first. HTTPS-only websites almost always keep an HTTP site live on port 80 for redirection to the HTTPS site. An attacker can still intercept unencrypted HTTP traffic on the HTTP request before the HTTPS redirection. &lt;abbr&gt;HSTS&lt;/abbr&gt; mitigates this: the website instructs the browser to prefer HTTPS for all future navigation. Websites can opt-in to a client-side list of domains forbidding plaintext HTTP, called the &lt;abbr&gt;HSTS&lt;/abbr&gt; Preload list. Membership in the preload list ensures that &lt;abbr&gt;TLS&lt;/abbr&gt; protects the initial request to a website, too.&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;dfn&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple&lt;/dfn&gt; applies the concepts behind &lt;abbr&gt;HSTS&lt;/abbr&gt; to &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple instead of HTTPS. In a response header, the website can tell browsers to expect stapling on all future renewals of a given certificate. Browsers will know to reject any certificates without a stapled &lt;abbr&gt;OCSP&lt;/abbr&gt; response, should a malicious server send a revoked certificate and omit the staple.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.google.com/document/d/1aISglJIIwglcOAhqNfK-2vtQl-_dWAapc-VLDh-9-BE/edit&#34;&gt;Chromium experimented with Expect-Staple in 2016&lt;/a&gt; and even had an initial preloaded list, but &lt;a href=&#34;https://issues.chromium.org/issues/41230705&#34;&gt;Chromium later retired all support&lt;/a&gt;. Then, it retired all support for &lt;abbr&gt;OCSP&lt;/abbr&gt; (including stapling and Must-Staple).&lt;/p&gt;
&lt;h3 id=&#34;poor-implementations&#34;&gt;Poor implementations&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.hboeck.de/archives/886-The-Problem-with-OCSP-Stapling-and-Must-Staple-and-why-Certificate-Revocation-is-still-broken.html&#34;&gt;The most popular Web servers (uncustomized Apache and Nginx) have poor support for stapling&lt;/a&gt;. I&amp;rsquo;m unfamiliar with Apache, but Nginx will happily serve a stale &lt;abbr&gt;OCSP&lt;/abbr&gt; response. &lt;a href=&#34;https://github.com/mozilla/server-side-tls/issues/283&#34;&gt;Nginx has a broken DNS resolver that can cache the wrong IP of an &lt;abbr&gt;OCSP&lt;/abbr&gt; stapling server&lt;/a&gt;. I worked around the issue with a custom version of &lt;a href=&#34;https://github.com/tomwassenberg/certbot-ocsp-fetcher&#34;&gt;certbot-ocsp-fetcher&lt;/a&gt;, but I don&amp;rsquo;t expect most system administrators to use a shell script to work around broken servers or to migrate to something that gets it right (such as Caddy). When the most popular web servers ship broken stapling implementations for &lt;em&gt;years,&lt;/em&gt; we need to try something else.&lt;/p&gt;
&lt;h2 id=&#34;querying-abbrcrlabbr-shards&#34;&gt;Querying &lt;abbr&gt;CRL&lt;/abbr&gt; shards&lt;/h2&gt;
&lt;p&gt;Recall that most clients can&amp;rsquo;t query and update giant &lt;abbr&gt;CRLs&lt;/abbr&gt; directly. This inefficiency motivated the creation of &lt;abbr title=&#34;Online Certificate Status Protocol&#34;&gt;OCSP&lt;/abbr&gt;. Ballot SC-063 also permits &lt;abbr&gt;CAs&lt;/abbr&gt; to partition their &lt;abbr&gt;CRLs&lt;/abbr&gt; into smaller &amp;ldquo;shards&amp;rdquo;. Each shard has a publicly available URL.&lt;/p&gt;
&lt;p&gt;&lt;abbr&gt;OCSP&lt;/abbr&gt;-enabled certificates contain an &lt;abbr&gt;OCSP&lt;/abbr&gt; URL in their metadata for clients to submit &lt;abbr&gt;OCSP&lt;/abbr&gt; queries. Let&amp;rsquo;s Encrypt plans to replace these &lt;abbr&gt;OCSP&lt;/abbr&gt; URLs with the URL to a &lt;abbr&gt;CRL&lt;/abbr&gt; shard containing revocation information for that certificate. Instead of querying a &lt;abbr&gt;CA&amp;rsquo;s&lt;/abbr&gt; &lt;abbr&gt;OCSP&lt;/abbr&gt; endpoint, clients download the relevant &lt;abbr&gt;CRL&lt;/abbr&gt; shard containing the revocation status of several certificates at a time.&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Downloading the revocation status for many certificates represents a partial privacy improvement. Querying entire shards instead of individual domains adds entropy: a &lt;abbr&gt;CA&lt;/abbr&gt; doesn&amp;rsquo;t know which entry on a &lt;abbr&gt;CRL&lt;/abbr&gt; shard a client needs to check.&lt;/p&gt;
&lt;p&gt;Clients will also see bigger downloads, as shards have footprints several times the size of single &lt;abbr&gt;OCSP&lt;/abbr&gt; lookups. Remember that &amp;ldquo;modern&amp;rdquo; websites often contain sub-resources from many domains. As &lt;abbr&gt;CRL&lt;/abbr&gt; shard downloads accumulate, the small size savings over summarized &lt;abbr&gt;CRLs&lt;/abbr&gt; (see next section) might not justify the privacy risk.&lt;/p&gt;
&lt;p&gt;&lt;abbr&gt;CAs&lt;/abbr&gt; find this solution easier than &lt;abbr&gt;OCSP&lt;/abbr&gt;, but I don&amp;rsquo;t think this resolves most of the &lt;abbr&gt;OCSP&lt;/abbr&gt; issues clients experience. Directly querying &lt;abbr&gt;CRL&lt;/abbr&gt; shards only partially mitigates each of the four &lt;abbr&gt;OCSP&lt;/abbr&gt; issues I enumerated.&lt;/p&gt;
&lt;h2 id=&#34;client-side-summarized-abbrcrlsabbr&#34;&gt;Client-side summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&lt;/h2&gt;
&lt;p&gt;Browsers subset or compress the giant set of all &lt;abbr title=&#34;Certificate Revocation Lists&#34;&gt;CRLs&lt;/abbr&gt; into compressed client-side lists with frequent push-based updates to keep browsing traffic private. Chromium CRLSets subset the complete set of &lt;abbr&gt;CRLs&lt;/abbr&gt; with some inclusion criteria, while Mozilla&amp;rsquo;s CRLite uses Bloom filters to compress a list of all current and revoked certificates. &lt;a href=&#34;https://letsencrypt.org/2022/09/07/new-life-for-crls.html&#34;&gt;Let&amp;rsquo;s Encrypt refers to both technologies as &lt;dfn&gt;summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&lt;/dfn&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;googles-approach-crlsets&#34;&gt;Google&amp;rsquo;s approach: CRLSets&lt;/h3&gt;
&lt;p&gt;Chromium has a data set called &amp;ldquo;CRLSets&amp;rdquo;. &lt;dfn&gt;&lt;a href=&#34;https://www.chromium.org/Home/chromium-security/crlsets/&#34;&gt;CRLSets&lt;/a&gt;&lt;/dfn&gt; initially contained a small fraction of all unexpired and currently-revoked certificates, preferring high-impact and Extended-Validation sites over smaller, unimportant domains such as &lt;code&gt;seirdy.one&lt;/code&gt;. It later expanded to cover certain reasons for revocation.&lt;/p&gt;
&lt;p&gt;My search through scattered documentation ended with three excellent articles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.imperialviolet.org/2012/02/05/crlsets.html&#34;&gt;Revocation checking and Chrome’s &lt;abbr&gt;CRL&lt;/abbr&gt;&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.imperialviolet.org/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Adam&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Langley&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, published on &lt;time class=&#34;dt-published published&#34;&gt;2012-02-05&lt;/time&gt;&lt;/span&gt;, introduces the concept and motivation behind CRLSets.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.imperialviolet.org/2014/04/29/revocationagain.html&#34;&gt;Revocation still doesn’t work&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.imperialviolet.org/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Adam&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Langley&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, published on &lt;time class=&#34;dt-published published&#34;&gt;2014-04-19&lt;/time&gt;&lt;/span&gt;, explains why the Chromium team didn&amp;rsquo;t design CRLSets to scale to all revoked certs. He suggests probabilistic data structures but cites their inherent error rate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://doi.org/10.1145/2815675.2815685&#34;&gt;An End-to-End Measurement of Certificate Revocation in the Web’s &lt;abbr title=&#34;Public Key Infrastructure&#34;&gt;PKI&lt;/abbr&gt;&lt;/a&gt;&lt;/cite&gt;, published on &lt;time class=&#34;dt-published published&#34;&gt;2015-10-28&lt;/time&gt;&lt;/span&gt;, evaluates several certificate revocation mechanisms and finds that CRLSets covered 0.35% of all revoked certificates.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In 2024 (this year, at the time of publishing), Chromium expanded CRLSets to cover compromised keys to improve the situation. CRLSets still don&amp;rsquo;t cover mass revocation events due to scalability issues.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;We&amp;rsquo;ve added support for certificate revocations due to key compromise to CRLSet, and enabled enforcement. Any certificate revoked with the key compromise reason code should now be blocked by Chrome clients within 24-48 hours. This approach should work for day-to-day revocation, but will not work for mass revocation events, due to a limit on the max size of a CRLSet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.chromium.org/Home/chromium-security/quarterly-updates/#q2-2024&#34;&gt;Chrome Security 2024 Q2 Update&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Given the subset of revoked certificates covered by CRLSets, I don&amp;rsquo;t consider them a robust solution to certificate revocation. This remains Chromium&amp;rsquo;s single current method for certificate revocation. Firefox used a similar mechanism called OneCRL, but it later migrated to a new approach called CRLite with full coverage.&lt;/p&gt;
&lt;h3 id=&#34;mozillas-approach-crlite&#34;&gt;Mozilla&amp;rsquo;s approach: CRLite&lt;/h3&gt;
&lt;p&gt;The second article by Adam Langley mentioned compressing certificate revocation lists into probabilistic error-prone data structures for better coverage with a small size. Firefox&amp;rsquo;s &lt;dfn&gt;&lt;a href=&#34;https://blog.mozilla.org/security/2020/01/09/crlite-part-2-end-to-end-design/&#34;&gt;CRLite&lt;/a&gt;&lt;/dfn&gt; takes this approach with Bloom filters but without the errors.&lt;/p&gt;
&lt;p&gt;Certain browsers (Safari, Chromium/Edge) require &lt;abbr&gt;CAs&lt;/abbr&gt; to participate in &lt;dfn&gt;Certificate Transparency (&lt;abbr&gt;CT&lt;/abbr&gt;)&lt;/dfn&gt;. Certificate Transparency logs are append-only distributed ledgers that publicize all &lt;abbr&gt;CA&lt;/abbr&gt;-issued certificates for public scrutiny.&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt; All certificates in &lt;abbr&gt;CT&lt;/abbr&gt; receive a signed certificate timestamp (&lt;abbr&gt;SCT&lt;/abbr&gt;) cryptographically proving their presence in a &lt;abbr&gt;CT&lt;/abbr&gt; log, which browsers can check. Safari, Chromium, and derivatives perform these checks; Firefox currently lacks support for &lt;abbr&gt;CT&lt;/abbr&gt;.&lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The CRLite Bloom filter generation process can compare the filter against actual &lt;abbr&gt;CT&lt;/abbr&gt; logs to remove all errors. The result has &lt;em&gt;complete&lt;/em&gt; coverage of certificate revocations with a tiny footprint and an error rate of zero!&lt;/p&gt;
&lt;p&gt;CRLite has a much smaller storage footprint than the hundreds of megabytes CRLSets would need for complete coverage. I still find this footprint too large for sufficiently constrained clients. When it first rolled out, it weighed 10 megabytes with a 580 kilobyte daily download for updates. CRLite&amp;rsquo;s footprint has at least doubled since then and continues to grow.&lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;apples-approach-validapplecom&#34;&gt;Apple&amp;rsquo;s approach: valid.apple.com&lt;/h3&gt;
&lt;p&gt;Apple adopted an approach similar to CRLite using Bloom filters; it&amp;rsquo;s known as &amp;ldquo;valid.apple.com&amp;rdquo;, or simply &amp;ldquo;valid&amp;rdquo;. I found &lt;span
	class=&#34;h-cite&#34;&gt;a now-unlisted &lt;abbr title=&#34;Worldwide Developers Conference&#34;&gt;WWDC&lt;/abbr&gt; 2017 presentation called &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://devstreaming-cdn.apple.com/videos/wwdc/2017/701jvytnoey2yc7222/701/701_hd_your_apps_and_evolving_network_security_standards.mp4&#34;&gt;Your Apps and Evolving Network Security&lt;/a&gt;&lt;/cite&gt; (&lt;span&gt;video/quicktime&lt;/span&gt;); the relevant part begins around &lt;time datetime=&#34;PT17M45S&#34;&gt;00:17:45&lt;/time&gt;.&lt;/span&gt; According to the 2017 presentation, when a lookup against Apple&amp;rsquo;s summarized &lt;abbr&gt;CRL&lt;/abbr&gt; has a positive signal, clients perform an &lt;abbr&gt;OCSP&lt;/abbr&gt; lookup when no stapled response exists.&lt;/p&gt;
&lt;p&gt;This approach reduces the number of live &lt;abbr&gt;OCSP&lt;/abbr&gt; queries to leak less traffic and slow down fewer connections. At the time of writing, the device I tested still makes regular live &lt;abbr&gt;OCSP&lt;/abbr&gt; checks.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t discuss valid.apple.com in detail because I&amp;rsquo;m unfamiliar with Apple&amp;rsquo;s approach, but this article would be incomplete without mentioning it. Braver souls can &lt;a href=&#34;https://opensource.apple.com/source/Security/&#34;&gt;browse Apple&amp;rsquo;s maze of public source code&lt;/a&gt; or &lt;a href=&#34;https://developer.apple.com/documentation/security/policies&#34;&gt;Apple&amp;rsquo;s API documentation for Web &lt;abbr&gt;PKI&lt;/abbr&gt; policies&lt;/a&gt;. valid.apple.com lacks any meaningful documentation.&lt;/p&gt;
&lt;p&gt;The documentation I cited comes from seven years ago. I suspect the approach has changed: the devices I tested seemed to make OCSP requests for every domain, and &lt;a href=&#34;https://forums.developer.apple.com/forums/thread/706629&#34;&gt;a thread on Apple Developer Forums&lt;/a&gt; seems to indicate that Apple stopped using client-side summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;. I expect major changes coming soon: Apple voted to make &lt;abbr&gt;OCSP&lt;/abbr&gt; optional in SC-064.&lt;/p&gt;
&lt;h3 id=&#34;shortcomings-of-summarized-abbrcrlsabbr&#34;&gt;Shortcomings of summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&lt;/h3&gt;
&lt;p&gt;As shown in the earlier section, revocation data sets such as CRLSets can&amp;rsquo;t scale to cover all revoked certificates. Probabilistic filters can, but both have additional issues.&lt;/p&gt;
&lt;p&gt;Summarized &lt;abbr title=&#34;Certificate Revocation Lists&#34;&gt;CRLs&lt;/abbr&gt; make sense for browsers, but not for smaller clients. cURL, small chat apps, mail clients, feed readers, weather notifications, etc. all use HTTPS and all need a summarized &lt;abbr&gt;CRL&lt;/abbr&gt; updated every few hours. This creates the need for an operating-system-managed summarized &lt;abbr&gt;CRL&lt;/abbr&gt;, which I doubt would work well if OS-managed certificate bundles serve any indication.&lt;/p&gt;
&lt;p&gt;Tiny embedded clients, Internet of Things devices, machines running ancient releases of stable-release distros,&lt;sup id=&#34;fnref:17&#34;&gt;&lt;a href=&#34;#fn:17&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;17&lt;/a&gt;&lt;/sup&gt; retro computers, etc. won&amp;rsquo;t constantly update an evergreen multi-megabyte revocation filter. Getting a live-updating compressed summarized &lt;abbr&gt;CRL&lt;/abbr&gt; on short-lived spin-up-spin-down servers might require effort from cloud vendors. Short-lived certificates make for a more realistic option to cater to such clients.&lt;/p&gt;
&lt;h3 id=&#34;lets-revoke&#34;&gt;Let&amp;rsquo;s Revoke&lt;/h3&gt;
&lt;p&gt;Unlike the other options in this section, &lt;a href=&#34;https://www.ndss-symposium.org/ndss-paper/lets-revoke-scalable-global-certificate-revocation/&#34;&gt;Let&amp;rsquo;s Revoke&lt;/a&gt; is just a proposal. Like CRLite, Let&amp;rsquo;s Revoke involves pushing all active and revoked certificates to a client in a highly-compressed form. However, it scales far better than existing options.&lt;/p&gt;
&lt;p&gt;&lt;dfn&gt;Let&amp;rsquo;s Revoke&lt;/dfn&gt; requires changes from &lt;abbr title=&#34;Certificate Authorities&#34;&gt;CAs&lt;/abbr&gt;: they need to generate Certificate Revocation Vectors (CRVs), small bit-vectors, and include them in every issued certificate. Under Let&amp;rsquo;s Revoke, a &lt;abbr&gt;CA&lt;/abbr&gt; pushes an incrementally-updated, highly-compressed archive of all CRVs for active revoked certificates to clients. Clients then use the archive to look up every certificate from that &lt;abbr&gt;CA&lt;/abbr&gt;. Let&amp;rsquo;s Revoke uses a fraction of CRLite&amp;rsquo;s storage footprint.&lt;/p&gt;
&lt;p&gt;For extra-constrained clients, the &lt;abbr&gt;CA&lt;/abbr&gt; can offer pull-based Let&amp;rsquo;s Revoke checks similar to &lt;abbr&gt;OCSP&lt;/abbr&gt; and querying &lt;abbr&gt;CRL&lt;/abbr&gt; shards. I&amp;rsquo;ll disregard live Let&amp;rsquo;s Revoke lookups in this article, as &lt;abbr&gt;CAs&lt;/abbr&gt; have already settled on using &lt;abbr&gt;CRL&lt;/abbr&gt; shards for live lookups as the successor to &lt;abbr&gt;OCSP&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;Getting all &lt;abbr&gt;CAs&lt;/abbr&gt; on board will prove difficult: getting them on board with certificate transparency, signed certificate timestamps, and &lt;abbr&gt;CRLs&lt;/abbr&gt; took a long time. Let&amp;rsquo;s Revoke only offers binary information about revocation status (no reasons, no revocation timestamp, etc.), so clients capable of handling CRLite&amp;rsquo;s footprint might find Let&amp;rsquo;s Revoke less useful. However, its ability to scale with a tiny footprint makes it promising for lightweight clients such as Internet of Things devices.&lt;/p&gt;
&lt;h2 id=&#34;abbracmeabbr-renewal-information-abbrariabbr&#34;&gt;&lt;abbr&gt;ACME&lt;/abbr&gt; Renewal Information (&lt;abbr&gt;ARI&lt;/abbr&gt;)&lt;/h2&gt;
&lt;p&gt;&lt;dfn&gt;&lt;abbr&gt;ACME&lt;/abbr&gt; Renewal Information (&lt;abbr&gt;ARI&lt;/abbr&gt;)&lt;/dfn&gt; is a protocol that notifies a server&amp;rsquo;s &lt;abbr&gt;ACME&lt;/abbr&gt; client when a certificate needs renewal. It can tell an &lt;abbr&gt;ACME&lt;/abbr&gt; client when a certificate grows stale (e.g., after &lt;time datetime=&#34;PT1440H&#34;&gt;60 days&lt;/time&gt; for a &lt;time datetime=&#34;PT2160H&#34;&gt;90-day&lt;/time&gt; certificate) or upon certificate revocation to facilitate quick renewal.&lt;/p&gt;
&lt;p&gt;Other revocation checks on this page ensure clients don&amp;rsquo;t trust revoked certificates. &lt;abbr&gt;ARI&lt;/abbr&gt; ensures servers don&amp;rsquo;t offer them. Even though &lt;abbr&gt;ARI&lt;/abbr&gt; isn&amp;rsquo;t a revocation check, an article describing the complete landscape of revocation checking should at least mention it.&lt;/p&gt;
&lt;p&gt;&lt;abbr&gt;ARI&lt;/abbr&gt; complements other forms of revocation. Both &lt;abbr&gt;ARI&lt;/abbr&gt; and &lt;abbr title=&#34;Online Certificate Status Protocol&#34;&gt;OCSP&lt;/abbr&gt; Stapling get servers with long-lived certificates to check in with &lt;abbr&gt;CAs&lt;/abbr&gt; more often to ensure that their certificates remain unrevoked.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://go-acme.github.io/lego/&#34;&gt;lego&lt;/a&gt; &lt;abbr&gt;ACME&lt;/abbr&gt; client supports &lt;abbr&gt;ARI&lt;/abbr&gt; thanks to contributions from Let&amp;rsquo;s Encrypt. See &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://letsencrypt.org/2024/04/25/guide-to-integrating-ari-into-existing-acme-clients&#34;&gt;An Engineer’s Guide to Integrating &lt;abbr&gt;ARI&lt;/abbr&gt; into Existing &lt;abbr&gt;ACME&lt;/abbr&gt; Clients&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://github.com/beautifulentropy&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Samantha&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Frank&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; for more on the implementation.&lt;/p&gt;
&lt;h2 id=&#34;short-lived-certificates&#34;&gt;Short-lived certificates&lt;/h2&gt;
&lt;p&gt;Recall that &lt;abbr&gt;CAs&lt;/abbr&gt; have a deadline to revoke a certificate; seven days represents the longest possible deadline. A certificate with a lifetime shorter than this can abstain from both &lt;abbr&gt;OCSP&lt;/abbr&gt; and &lt;abbr&gt;CRLs&lt;/abbr&gt;.&lt;sup id=&#34;fnref:18&#34;&gt;&lt;a href=&#34;#fn:18&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;If we reduce a certificate&amp;rsquo;s lifetime to less than one week, revocation becomes much less of a problem. Instead of &amp;ldquo;revoking&amp;rdquo; a certificate, a &lt;abbr&gt;CA&lt;/abbr&gt; stops re-issuing certificates for a domain and waits for the most recent certificate to expire. The European Telecommunications Standards Institute (&lt;abbr&gt;ETSI&lt;/abbr&gt;) calls certificates with a lifetime of no longer than &lt;time datetime=&#34;PT168H&#34;&gt;seven days&lt;/time&gt; &lt;dfn&gt;short-lived certificates&lt;/dfn&gt;.&lt;sup id=&#34;fnref:19&#34;&gt;&lt;a href=&#34;#fn:19&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;19&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Live &lt;abbr&gt;OCSP&lt;/abbr&gt; checks, sharded &lt;abbr&gt;CRL&lt;/abbr&gt; lookups, and summarized &lt;abbr&gt;CRLs&lt;/abbr&gt; add centralized points of failure for client-side revocation look-ups. Attackers can block component updates, online &lt;abbr&gt;OCSP&lt;/abbr&gt; checks, or &lt;abbr&gt;CRL&lt;/abbr&gt; shard fetches.&lt;sup id=&#34;fnref:20&#34;&gt;&lt;a href=&#34;#fn:20&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;20&lt;/a&gt;&lt;/sup&gt; Short-lived certificates add no more points of failure.&lt;/p&gt;
&lt;p&gt;Short-lived certificates come with their own set of challenges:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Webmasters have narrow time windows to fix certificate issues. They&amp;rsquo;ll need to set up monitoring, alerts, and backup &lt;abbr&gt;CAs&lt;/abbr&gt; should they not want a &lt;abbr&gt;CA&amp;rsquo;s&lt;/abbr&gt; reliability to bottleneck their own.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;abbr&gt;CAs&lt;/abbr&gt; need to issue certificates &lt;em&gt;far&lt;/em&gt; more often, increasing their load. Phasing out &lt;abbr&gt;OCSP&lt;/abbr&gt; frees up some resources for them to do this, although &lt;abbr&gt;CAs&lt;/abbr&gt; need much fewer resources for serving an &lt;abbr&gt;OCSP&lt;/abbr&gt; response than for renewing a certificate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;abbr&gt;CAs&lt;/abbr&gt; need to improve their availability. Large ones can take down millions of services by going offline long enough.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overcoming these obstacles will take much work. &lt;abbr&gt;ACME-STAR&lt;/abbr&gt; and delegated credentials for &lt;abbr title=&#34;Transit Layer Security&#34;&gt;TLS&lt;/abbr&gt; look like promising attempts to shorten the longevity of certificate trust in the Web &lt;abbr title=&#34;Public Key Infrastructure&#34;&gt;PKI&lt;/abbr&gt;.&lt;/p&gt;
&lt;h3 id=&#34;abbracme-starabbr&#34;&gt;&lt;abbr&gt;ACME-STAR&lt;/abbr&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.rfc-editor.org/rfc/rfc8739.html&#34;&gt;&lt;abbr title=&#34;Request for Comments&#34;&gt;RFC&lt;/abbr&gt; 8739: Support for Short-Term, Automatically Renewed (&lt;abbr&gt;STAR&lt;/abbr&gt;) Certificates in the Automated Certificate Management Environment (&lt;abbr&gt;ACME&lt;/abbr&gt;)&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; outlines how &lt;abbr&gt;ACME-STAR&lt;/abbr&gt; improves efficiency when issuing short-lived certificates at scale.&lt;/p&gt;
&lt;p&gt;Requesting a certificate from a &lt;abbr&gt;CA&lt;/abbr&gt; requires the &lt;abbr&gt;CA&lt;/abbr&gt; to issue a certificate immediately, even during heavy load. Shrinking the issuance window from two months to mere days would dramatically increase this load. We require an alternative to issuing certificates on-demand. &lt;abbr&gt;CAs&lt;/abbr&gt; already generate &lt;abbr title=&#34;Online Certificate Status Protocol&#34;&gt;OCSP&lt;/abbr&gt; responses ahead of time and offer them for &lt;abbr&gt;ACME&lt;/abbr&gt; clients to download and staple, so why should they handle short-lived certificates differently?&lt;/p&gt;
&lt;p&gt;With &lt;dfn&gt;&lt;abbr&gt;ACME-STAR&lt;/abbr&gt;&lt;/dfn&gt;, &lt;abbr&gt;CAs&lt;/abbr&gt; can schedule certificate re-issuance, generating them ahead of time for &lt;abbr&gt;ACME&lt;/abbr&gt; clients to download later. &lt;abbr&gt;ACME&lt;/abbr&gt; clients no longer need to request certificate generation; instead, they regularly re-fetch the most recently generated certificate.&lt;/p&gt;
&lt;h3 id=&#34;delegated-credentials&#34;&gt;Delegated credentials&lt;/h3&gt;
&lt;p&gt;An &lt;dfn&gt;Identifier Owner (&lt;abbr&gt;IdO&lt;/abbr&gt;)&lt;/dfn&gt; is a party that operates and controls an identifier (usually a domain name&lt;sup id=&#34;fnref:21&#34;&gt;&lt;a href=&#34;#fn:21&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;21&lt;/a&gt;&lt;/sup&gt;). Traditionally, &lt;abbr&gt;CAs&lt;/abbr&gt; issue a &lt;abbr title=&#34;Transit Layer Security&#34;&gt;TLS&lt;/abbr&gt; certificate to an &lt;abbr&gt;ACME&lt;/abbr&gt; client operated by the &lt;abbr&gt;IdO&lt;/abbr&gt;. Often, the &lt;abbr&gt;IdO&lt;/abbr&gt; delegates another party with more infrastructure to serve responses on its behalf. How do we handle certificate issuance when the &lt;abbr&gt;IdO&lt;/abbr&gt; delegates a separate &lt;abbr&gt;ACME&lt;/abbr&gt; client operator?&lt;/p&gt;
&lt;p&gt;Servers fronted by Content Delivery Networks (&lt;abbr&gt;CDNs&lt;/abbr&gt;) generally trust the &lt;abbr&gt;CDN&lt;/abbr&gt; to handle &lt;abbr&gt;TLS&lt;/abbr&gt;. The &lt;abbr&gt;CDN&lt;/abbr&gt; has a &lt;abbr&gt;TLS&lt;/abbr&gt; certificate that verifies a trusted link between ownership of the certificate and use of the domain name. The &lt;abbr&gt;TLS&lt;/abbr&gt; certificate doesn&amp;rsquo;t, however, prove any involvement from the &lt;abbr&gt;IdO&lt;/abbr&gt;, the one who holds and controls the domain name. The &lt;abbr&gt;IdO&lt;/abbr&gt; ostensibly communicates with the &lt;abbr&gt;CDN&lt;/abbr&gt; over one &lt;abbr&gt;TLS&lt;/abbr&gt; connection, and the &lt;abbr&gt;CDN&lt;/abbr&gt; communicates with clients using a separate &lt;abbr&gt;TLS&lt;/abbr&gt; connection. We extend the trusted &lt;abbr&gt;CDN&lt;/abbr&gt;-to-domain link to include the &lt;abbr&gt;IdO&lt;/abbr&gt;-to-&lt;abbr&gt;CDN&lt;/abbr&gt; link with a delegated credential.&lt;/p&gt;
&lt;p&gt;A &lt;dfn&gt;delegated credential&lt;/dfn&gt; is a short-lived certificate that the delegate (such as a &lt;abbr&gt;CDN&lt;/abbr&gt;) frequently re-generates on behalf of its &lt;abbr&gt;IdO&lt;/abbr&gt;. A &lt;abbr&gt;CA&amp;rsquo;s&lt;/abbr&gt; private keys sign a normal &lt;abbr&gt;TLS&lt;/abbr&gt; certificate to show approval from the &lt;abbr&gt;CA&lt;/abbr&gt;. A delegated credential receives one more signature: the &lt;abbr&gt;IdO&amp;rsquo;s&lt;/abbr&gt; longer-lived &lt;abbr&gt;TLS&lt;/abbr&gt; key &lt;em&gt;also&lt;/em&gt; signs the delegated credential.&lt;/p&gt;
&lt;p&gt;Delegated credentials solve three problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clients can now verify that the &lt;abbr&gt;TLS&lt;/abbr&gt; key sent by a &lt;abbr&gt;CDN&lt;/abbr&gt; has approval from both the &lt;abbr&gt;CDN&lt;/abbr&gt; and the &lt;abbr&gt;IdO&lt;/abbr&gt; behind the &lt;abbr&gt;CDN&lt;/abbr&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clients receive the benefits of short-lived certificates: they don&amp;rsquo;t have to worry about revocation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We have a standard, vendor-neutral way for &lt;abbr&gt;CDNs&lt;/abbr&gt; to generate certificates on behalf of an &lt;abbr&gt;IdO&lt;/abbr&gt; without access to the &lt;abbr&gt;IdO&amp;rsquo;s&lt;/abbr&gt; private keys, in a more efficient manner than current approaches such as &lt;a href=&#34;https://blog.cloudflare.com/announcing-keyless-ssl-all-the-benefits-of-cloudflare-without-having-to-turn-over-your-private-ssl-keys/&#34;&gt;Cloudflare&amp;rsquo;s &amp;ldquo;Keyless SSL&amp;rdquo;&lt;/a&gt;.&lt;sup id=&#34;fnref:22&#34;&gt;&lt;a href=&#34;#fn:22&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;22&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Delegated credentials solve revocation of the certificate issued to the &lt;abbr&gt;CDN&lt;/abbr&gt;, but not to the &lt;abbr&gt;IdO&lt;/abbr&gt;. &lt;strong&gt;Should a &lt;abbr&gt;CA&lt;/abbr&gt; revoke an &lt;abbr&gt;IdO&amp;rsquo;s&lt;/abbr&gt; long-lived certificate, we need another revocation solution.&lt;/strong&gt; Delegated credentials address the need to &lt;em&gt;distrust&lt;/em&gt; &lt;abbr&gt;CDNs&lt;/abbr&gt;, so we can&amp;rsquo;t rely on &lt;abbr&gt;CDNs&lt;/abbr&gt; to respond to the revocation of the &lt;abbr&gt;IdO&lt;/abbr&gt; certificate.&lt;/p&gt;
&lt;p&gt;I still find delegated credentials worthwhile in the context of revocation. They could lay a foundation for future advancements to enable revocation checking of both certificates: the delegate&amp;rsquo;s and the &lt;abbr&gt;IdO&amp;rsquo;s&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.rfc-editor.org/rfc/rfc9345.html&#34;&gt;&lt;abbr title=&#34;Request for Comments&#34;&gt;RFC&lt;/abbr&gt; 9345: Delegated Credentials for &lt;abbr&gt;TLS&lt;/abbr&gt; and &lt;abbr&gt;DTLS&lt;/abbr&gt;&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; outlines the mechanism that Cloudflare, Facebook, and Firefox use for delegated credentials with other rationales.&lt;/p&gt;
&lt;h3 id=&#34;abbracme-starabbr-delegation&#34;&gt;&lt;abbr&gt;ACME-STAR&lt;/abbr&gt; Delegation&lt;/h3&gt;
&lt;p&gt;&lt;abbr title=&#34;ACME Short-Term, Automatically Renewed&#34;&gt;ACME-STAR&lt;/abbr&gt; lays its own foundation for delegated credentials in &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.rfc-editor.org/rfc/rfc9115.html&#34;&gt;&lt;abbr&gt;RFC&lt;/abbr&gt; 9115: An Automatic Certificate Management Environment (&lt;abbr&gt;ACME&lt;/abbr&gt;) Profile for Generating Delegated Certificates&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t feel too optimistic about this proposal: the version of delegated credentials used by Cloudflare, Facebook, and Firefox doesn&amp;rsquo;t use &lt;abbr&gt;ACME-STAR&lt;/abbr&gt;, let alone &lt;abbr&gt;ACME-STAR&lt;/abbr&gt; Delegation. Its publication came almost two years after the final revision of &lt;abbr&gt;ACME-STAR&lt;/abbr&gt; Delegation, and it doesn&amp;rsquo;t mention &lt;abbr&gt;ACME-STAR&lt;/abbr&gt; Delegation anywhere in its &amp;ldquo;Related Work&amp;rdquo; section.&lt;/p&gt;
&lt;p&gt;For an introduction to the proposal, see &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://yaronf.svbtle.com/certificate-delegation-with-acme-and-star-certificates&#34;&gt;Certificate Delegation with ACME and STAR Certificates&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://yaronf.svbtle.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Yaron&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Scheffer&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;, one of its co-authors.&lt;/p&gt;
&lt;h2 id=&#34;own-proposals&#34;&gt;My proposals&lt;/h2&gt;
&lt;h3 id=&#34;no-spof&#34;&gt;Eliminating single points of failure&lt;/h3&gt;
&lt;p&gt;Browser-summarized CRLs and live checks have a single point of failure: if a malicious party blocks component updates or live checks, they can block revocation information for a compromised certificate. We can mitigate this issue by decentralizing the points of failure. I like the idea of using &lt;a href=&#34;https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html&#34;&gt;Signed HTTP Exchanges (&lt;abbr&gt;SXGs&lt;/abbr&gt;)&lt;/a&gt; to enable other parties to serve revocation filters while verifying their authenticity. I recall hearing proposals for serving them over a &lt;abbr title=&#34;Web Real Time Communication&#34;&gt;WebRTC&lt;/abbr&gt; or WebTransport-based peer-to-peer swarm resembling WebTorrent.&lt;/p&gt;
&lt;p&gt;We can also use &lt;abbr&gt;SXGs&lt;/abbr&gt; to distribute CRLs or CRL shards.&lt;/p&gt;
&lt;h3 id=&#34;enforcing-stc&#34;&gt;Enforcing short-term certificates&lt;/h3&gt;
&lt;p&gt;I have two proposals that can work alongside existing proposals for short-lived certificates.&lt;/p&gt;
&lt;p&gt;Today, Certificate Authority Authorization (&lt;abbr&gt;CAA&lt;/abbr&gt;) DNS records restrict the issuance of certificates in several ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Restrict &lt;abbr&gt;CAs&lt;/abbr&gt; permitted to issue certificates to a given domain.&lt;/li&gt;
&lt;li&gt;Restrict domain validation methods accepted (&lt;abbr&gt;RFC&lt;/abbr&gt; 8657).&lt;/li&gt;
&lt;li&gt;Restrict &lt;abbr&gt;ACME&lt;/abbr&gt; account URIs for a given &lt;abbr&gt;CA&lt;/abbr&gt; (also &lt;abbr&gt;RFC&lt;/abbr&gt; 8657).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;abbr&gt;CAA&lt;/abbr&gt; records should receive two more extensions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Restrict issuance to short-lived certificates.&lt;/li&gt;
&lt;li&gt;Restrict approved delegates for delegated credentials.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the first extension, an attacker who triggers a misissuance would compromise it for a few days or hours rather than months. The second extension limits the potential for rogue delegates to serve traffic on behalf of an &lt;abbr&gt;IdO&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;I want to see the protections offered by Expect-Staple preloading for short-lived certificates. HTTPS Resource Records (&lt;abbr&gt;RRs&lt;/abbr&gt;) or client-side preload lists can proactively tell clients to distrust any long-lived certificate for a domain.&lt;sup id=&#34;fnref1:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;These two proposals might initially seem identical and redundant, but they serve different purposes. A &lt;abbr&gt;CAA&lt;/abbr&gt; extension tells &lt;abbr&gt;CAs&lt;/abbr&gt; not to issue long-lived certificates; HTTPS clients ignore these. An HTTPS &lt;abbr&gt;RR&lt;/abbr&gt; or client-side preload list tells clients not to trust a long-lived certificate if one already exists. Both proposals work together to protect against long-lived compromises on two fronts.&lt;/p&gt;
&lt;h2 id=&#34;incremental-change-shorter-long-lived-certificates&#34;&gt;Incremental change: shorter long-lived certificates&lt;/h2&gt;
&lt;p&gt;Every week we shave from the average certificate&amp;rsquo;s lifetime means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One less week an attacker has to exfiltrate a key.&lt;/li&gt;
&lt;li&gt;One less week a compromised cert has to stay in a revocation list.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every reduction we make to certificate lifetimes translates to smaller, more manageable revocation lists. Client-side Bloom filters can shrink, &lt;abbr&gt;CAs&lt;/abbr&gt; can more gradually scale up and address difficulties with shorter lifetimes, and everybody has a lower likelihood of trusting a compromised certificate.&lt;/p&gt;
&lt;p&gt;We don&amp;rsquo;t have to go down to ten-day lifetimes right away. I propose starting by &lt;strong&gt;shrinking lifetimes from three months to six weeks,&lt;/strong&gt; with biweekly renewal. This would encourage webmasters to set up alerting systems for renewal failures, as they&amp;rsquo;ll have just two weeks to notice failures. It&amp;rsquo;ll also potentially reduce the growth rate of revocation filters until we adopt better options.&lt;/p&gt;
&lt;h3 id=&#34;requesting-a-shorter-lifetime&#34;&gt;Requesting a shorter lifetime&lt;/h3&gt;
&lt;p&gt;&lt;abbr&gt;ACME&lt;/abbr&gt; clients can set a &lt;code&gt;notBefore&lt;/code&gt; and &lt;code&gt;notAfter&lt;/code&gt; parameter in their certificate request to customize the exact certificate lifetimes. &lt;abbr title=&#34;Certificate Authorities&#34;&gt;CAs&lt;/abbr&gt; that support this feature include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sectigo (through ZeroSSL)&lt;/li&gt;
&lt;li&gt;Google Trust Services&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;abbr&gt;ACME&lt;/abbr&gt; clients that support these parameters include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lego (recommended)&lt;/li&gt;
&lt;li&gt;acme.sh&lt;sup id=&#34;fnref:23&#34;&gt;&lt;a href=&#34;#fn:23&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;23&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Posh-ACME&lt;/li&gt;
&lt;/ul&gt;
&lt;section role=&#34;doc-conclusion&#34;&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With &lt;abbr title=&#34;Online Certificate Status Protocol&#34;&gt;OCSP&lt;/abbr&gt; on its way out, the end draws near even for robust &lt;abbr&gt;OCSP&lt;/abbr&gt;-based options such as &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple. The future lies in:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Live lookups using sharded &lt;abbr title=&#34;Certificate Revocation Lists&#34;&gt;CRLs&lt;/abbr&gt;&lt;/li&gt;
&lt;li&gt;Summarized &lt;abbr&gt;CRLs&lt;/abbr&gt; such as CRLite and Let&amp;rsquo;s Revoke&lt;/li&gt;
&lt;li&gt;Short-lived certificates using &lt;abbr&gt;ACME-STAR&lt;/abbr&gt;. Delegated credentials only partially address revocation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Live sharded-&lt;abbr&gt;CRL&lt;/abbr&gt; lookups resemble live &lt;abbr&gt;OCSP&lt;/abbr&gt; lookups. They differ in their lower operational complexity for &lt;abbr&gt;CAs&lt;/abbr&gt;, added noise for a slight privacy improvement, and larger downloads. Summarized &lt;abbr&gt;CRLs&lt;/abbr&gt; seem like the opposite approach to &lt;abbr&gt;OCSP&lt;/abbr&gt;, downloading all current revocations in advance and checking them locally.&lt;/p&gt;
&lt;p&gt;I find short-lived certificates a spiritual successor to both by applying &lt;abbr&gt;OCSP&amp;rsquo;s&lt;/abbr&gt; approach to certificate issuance. All three options represent improvements, but I find short-lived certificates more robust. Unfortunately, without better tools, short-lived certificates place a greater burden on webmasters. The fact that &lt;code&gt;seirdy.one&lt;/code&gt; has a three-month certificate at the time of writing (admittedly, with &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple) illustrates the height of this barrier as of late 2024.&lt;/p&gt;
&lt;p&gt;That said, not all sites need to adopt short-lived certificates. Client-side revocation filters increase in total size and daily download footprint every year, but a large enough share of sites adopting short-lived certificates would mitigate that trend.&lt;/p&gt;
&lt;p&gt;We have so much more work to do. Most non-browser clients support &lt;em&gt;none&lt;/em&gt; of the revocation solutions outlined on this page. All BoringSSL-based clients, including Chromium, have no support for &lt;abbr&gt;OCSP&lt;/abbr&gt; (including &lt;abbr&gt;OCSP&lt;/abbr&gt; stapling). This means most Web traffic lacks robust revocation checking. We need libraries that support delegated credentials. We need &lt;abbr&gt;CA&lt;/abbr&gt; support and  server tools for &lt;abbr&gt;ACME&lt;/abbr&gt; extensions, such as &lt;abbr&gt;ACME-STAR&lt;/abbr&gt;.&lt;/p&gt;
&lt;h3 id=&#34;aside-browser-wars&#34;&gt;Aside: browser wars&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://seirdy.one/notes/2022/07/12/firefox-hardening-progress/&#34;&gt;Firefox continues (rapidly) playing catch-up to Chromium on important aspects of browser security&lt;/a&gt;, but its security edges ahead in some areas. It&amp;rsquo;s the best at revocation checking, but the worst at alerting webmasters that they need to revoke.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Firefox has the best support for &lt;abbr&gt;OCSP&lt;/abbr&gt; (including &lt;abbr&gt;OCSP&lt;/abbr&gt; Must-Staple and an option to require &lt;abbr&gt;OCSP&lt;/abbr&gt; and make it hard-fail), years after Chromium removed all &lt;abbr&gt;OCSP&lt;/abbr&gt; support.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Firefox uses complete and error-free Bloom filters in CRLite. Chromium covers a fraction of all revoked certs in CRLSets. I&amp;rsquo;m too unfamiliar with Safari&amp;rsquo;s approach to comment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At the time of writing, Firefox stands alone as the single browser with support for delegated credentials.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For years, Firefox has also been the only one of the three major browsers to lack any support for Certificate Transparency enforcement. Without enforcing &lt;abbr&gt;CT&lt;/abbr&gt;, domain owners won&amp;rsquo;t know when misissued certificates exist. All the revocation &lt;em&gt;checking&lt;/em&gt; in the world won&amp;rsquo;t tell a domain owner when they need to revoke.&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&#34;doc-acknowledgments&#34;&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://www.agwa.name/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Andrew&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Ayer&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for giving me detailed feedback on an early draft. He offered feedback that significantly improved this article by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pointing out several areas needing elaboration.&lt;/li&gt;
&lt;li&gt;Linking me to Chromium&amp;rsquo;s Q2 2024 update to fix my outdated information.&lt;/li&gt;
&lt;li&gt;Highlighting at least six factual errors.&lt;/li&gt;
&lt;li&gt;introducing me to valid.apple.com.&lt;/li&gt;
&lt;li&gt;Telling me about the relevance of Firefox lacking &lt;abbr&gt;CT&lt;/abbr&gt; support.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://erincandescent.net/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Erin Alexis Owen Shepherd&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; also reviewed a draft. Among other feedback, they encouraged me to mention pre-&lt;abbr&gt;OCSP&lt;/abbr&gt; &lt;abbr&gt;CRLs&lt;/abbr&gt;; this was the only part of the history of revocation I hadn&amp;rsquo;t covered.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;#enforcing-stc&#34;&gt;the section with my proposals&lt;/a&gt; for an example of how an attacker can compromise certificate issuance for a domain unprotected by &lt;abbr title=&#34;Certificate authority Authorization&#34;&gt;CAA&lt;/abbr&gt; DNS records. An attacker might also steal your private keys, but at that point, you have worse things to worry about.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Relatively speaking, this part is &lt;em&gt;easier&lt;/em&gt; than revocation but that doesn&amp;rsquo;t make it &lt;em&gt;easy.&lt;/em&gt; High-volume free &lt;abbr&gt;CAs&lt;/abbr&gt; such as Let&amp;rsquo;s Encrypt can&amp;rsquo;t handle individual requests for revocation. They usually revoke certificates in bulk when they experience an issue.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;I noticed people referring to CRLSets and CRLite as types of &lt;abbr&gt;CRLs&lt;/abbr&gt; but I find the term inaccurate. A Certificate Revocation List contains revoked certificates for a given &lt;abbr&gt;CA&lt;/abbr&gt; complete with metadata about reasons for revocation; browsers&amp;rsquo; revocation databases accumulate and subset or compress all &lt;abbr&gt;CRLs&lt;/abbr&gt; into a single list or filter with limited metadata.&lt;/p&gt;
&lt;p&gt;I still needed a term that referred to CRLSets, CRLite, and Let&amp;rsquo;s Revoke. Let&amp;rsquo;s Encrypt picked &amp;ldquo;summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;&amp;rdquo;, so I decided to compromise and use their term despite my reservations.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Source: &lt;a href=&#34;https://w3techs.com/technologies/history_overview/ssl_certificate&#34;&gt;W3Techs&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;For more staff comments, see some forum replies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://community.letsencrypt.org/t/what-will-happen-to-must-staple/222397/7&#34;&gt;A multi-part answer to what will happen to Must-Staple&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://aarongable.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Aaron&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Gable&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://lobste.rs/s/k4uuth/intent_end_ocsp_service#c_bzhdvt&#34;&gt;We will make sure we have a solution for anyone with &lt;abbr&gt;OCSP&lt;/abbr&gt; must-staple enabled&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://mcpherrin.ca/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Matthew&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;McPherrin&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://news.ycombinator.com/item?id=41048161&#34;&gt;This is probably at least a year, if not more, away&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://mcpherrin.ca/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Matthew&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;McPherrin&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both staff members find &lt;abbr title=&#34;Online Certificate Status Protocol&#34;&gt;OCSP&lt;/abbr&gt;, even with Must-Staple, the wrong long-term solution.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;abbr&gt;ACME&lt;/abbr&gt; stands for &lt;a href=&#34;https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment&#34;&gt;Automatic Certificate Management Environment&lt;/a&gt;, the standard protocol for automating certificate management between certificate authorities and servers.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;I even used the &lt;code&gt;dfn&lt;/code&gt; HTML element like a good little HTML author. 🥺&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;See section 4.9.1.1 of the &lt;abbr&gt;CA&lt;/abbr&gt;/B Baseline Requirements&lt;sup id=&#34;fnref1:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; for &lt;time datetime=&#34;PT24H&#34;&gt;24-hour&lt;/time&gt; and &lt;time datetime=&#34;PT120H&#34;&gt;five-day&lt;/time&gt; deadlines. The next section (section 4.9.1.2) describes seven-day deadlines. Past compromise of a subscriber key, authorization during certificate requests, or domain validation leaves a &lt;abbr&gt;CA&lt;/abbr&gt; with &lt;time datetime=&#34;PT24H&#34;&gt;24 hours&lt;/time&gt; to revoke.&lt;/p&gt;
&lt;p&gt;The Baseline Requirements exempt short-lived certificates from this deadline. I find the tradeoff acceptable, given how many compromised certificates still won&amp;rsquo;t experience revocation in time but will be renewed.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;For all the requirements &lt;abbr&gt;CAs&lt;/abbr&gt; must obey, read &lt;a href=&#34;https://cabforum.org/working-groups/server/baseline-requirements/documents/&#34;&gt;the &lt;abbr&gt;CA&lt;/abbr&gt;/Browser Baseline Requirements&lt;/a&gt;. I recommend reading through them for a fascinating overview of what &lt;abbr&gt;CAs&lt;/abbr&gt; do.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;I oversimplified the nuance of the size increase. HTTPS clients that support &lt;abbr&gt;OCSP&lt;/abbr&gt; cache live &lt;abbr&gt;OCSP&lt;/abbr&gt; responses for a week, so later sessions will have a lower footprint than they would if the certificate had a stapled &lt;abbr&gt;OCSP&lt;/abbr&gt; response. The footprint of a webpage might eclipse the footprint of a stapled &lt;abbr&gt;OCSP&lt;/abbr&gt; response, but remember that HTTPS responses besides webpages exist. Instant messages, API responses, etc. tend to weigh less and often have significant latency constraints.&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.google.com/document/d/180T6cDSWPy54Rb5d6R4zN7MuLEMShaZ4IRLQgdPqE98/mobilebasic&#34;&gt;Ballot SC-064&amp;rsquo;s Google Doc for background, rationale, and considerations&lt;/a&gt; cites &lt;a href=&#34;https://docs.google.com/document/d/1C0i0pOaI84gNccGzREPOrr5kMfpYkUEr87cBMZ09q_4/mobilebasic&#34;&gt;a survey of all unexpired certificates at the time in &lt;abbr title=&#34;Certificate Transparency&#34;&gt;CT&lt;/abbr&gt; logs&lt;/a&gt;, finding that 0.0622% of all certificates used Must-Staple.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;I always found protecting the initial request with a client-side domain list a horrible, but effective, hack. We should have a way to query available connection methods for a domain using the correct venue for querying domain metadata set by a domain owner: DNS.&lt;/p&gt;
&lt;p&gt;We have a better solution today with HTTPS resource records! These specify how to access an HTTPS service before making an HTTPS connection. They list the availability of HTTP/2 and HTTP/3 (both require &lt;abbr title=&#34;Transport Layer Security&#34;&gt;TLS&lt;/abbr&gt;), an IPv4/IPv6 address, and Encrypted Client Hello keys.&lt;/p&gt;
&lt;p&gt;In an alternate timeline where &lt;abbr&gt;OCSP&lt;/abbr&gt; Expect-Staple took off, perhaps HTTPS resource records could include Expect-Staple metadata.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;If you&amp;rsquo;re too impatient to wait for shard URLs embedded in certificates to roll out, look up the &lt;abbr title=&#34;Certificate Revocation List&#34;&gt;CRL&lt;/abbr&gt; for a given certificate in &lt;a href=&#34;https://www.ccadb.org/resources&#34;&gt;the Common &lt;abbr&gt;CA&lt;/abbr&gt; Database (&lt;abbr&gt;CCADB&lt;/abbr&gt;)&lt;/a&gt;. All three major browser vendors require &lt;abbr&gt;CA&lt;/abbr&gt; participation in the &lt;abbr&gt;CCADB&lt;/abbr&gt;; it&amp;rsquo;s &lt;em&gt;the&lt;/em&gt; place to look for &lt;abbr&gt;CRLs&lt;/abbr&gt; today, and therefore critical to their generation of summarized &lt;abbr&gt;CRLs&lt;/abbr&gt;.&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;Note that &lt;abbr title=&#34;Certificate Transparency&#34;&gt;CT&lt;/abbr&gt; logs don&amp;rsquo;t specify revocation status. Revocation happens &lt;em&gt;after&lt;/em&gt; certificate issuance; the &lt;abbr&gt;CT&lt;/abbr&gt; log already lists the certificate by then.&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34;&gt;
&lt;p&gt;Follow Firefox&amp;rsquo;s progress for implementing &lt;abbr title=&#34;Certificate Transparency&#34;&gt;CT&lt;/abbr&gt; in &lt;a href=&#34;https://bugzilla.mozilla.org/show_bug.cgi?id=1281469&#34;&gt;Bug 1281469&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34;&gt;
&lt;p&gt;Updating summarized &lt;abbr&gt;CRLs&lt;/abbr&gt; requires browsers to make regular automatic connections by default. &lt;a href=&#34;https://seirdy.one/notes/2024/07/19/on-a-more-selective-google/&#34;&gt;I find browser patchsets to turn off all automated connections misguided&lt;/a&gt; partly because they break revocation.&amp;#160;&lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:17&#34;&gt;
&lt;p&gt;Here&amp;rsquo;s your regular reminder that &lt;a href=&#34;https://wiki.debian.org/LTS/Extended&#34;&gt;Debian Extended Long-Term Support exists&lt;/a&gt;. Debian 8 &amp;ldquo;Jessie&amp;rdquo;, released on &lt;time&gt;2015-04-25&lt;/time&gt;, will continue to keep security professionals up at night with officially-endorsed third-party limited commercial support from Freexian through &lt;time&gt;2025-06-30&lt;/time&gt;. Debian 12 support lasts till 2033.&amp;#160;&lt;a href=&#34;#fnref:17&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:18&#34;&gt;
&lt;p&gt;Yes, one week. Firefox skips revocation checking for certificates with a validity period shorter than &lt;time datetime=&#34;PT240H&#34;&gt;10 days&lt;/time&gt;. Until recently, &lt;abbr&gt;CAs&lt;/abbr&gt; and browsers agreed that the definition of a short-lived certificate required a validity period shorter than &lt;time datetime=&#34;PT240H&#34;&gt;10 days&lt;/time&gt;. The &lt;abbr&gt;CA&lt;/abbr&gt;/Browser Ballot SC-064 v4 specifies adopting the European Telecommunications Standards Institute (&lt;abbr&gt;ETSI&lt;/abbr&gt;) specification for short-lived certificates,&lt;sup id=&#34;fnref1:19&#34;&gt;&lt;a href=&#34;#fn:19&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;19&lt;/a&gt;&lt;/sup&gt; constraining their lifetime to the maximum time to process a revocation request. This will shorten the maximum lifetime of a short-lived certificate from 10 to &lt;time datetime=&#34;PT168H&#34;&gt;7 days&lt;/time&gt; by &lt;time&gt;2026-03-15&lt;/time&gt;.&amp;#160;&lt;a href=&#34;#fnref:18&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:19&#34;&gt;
&lt;p&gt;Fittingly, the canonical location of this &lt;abbr&gt;ETSI&lt;/abbr&gt; specification lives on a server experiencing live &lt;abbr&gt;OCSP&lt;/abbr&gt; failures. &lt;a href=&#34;https://web.archive.org/web/20240902154502if_/https://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.04.04_60/en_31941201v010404p.pdf&#34;&gt;I saved an archived copy of the &lt;abbr&gt;ETSI&lt;/abbr&gt; specification for certificate profiles&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:19&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:19&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:20&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;#no-spof&#34;&gt;my own proposals&lt;/a&gt; for a mitigation to summarized-CRLs&amp;rsquo; single point of failure.&amp;#160;&lt;a href=&#34;#fnref:20&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:21&#34;&gt;
&lt;p&gt;Valid identifiers in the Web &lt;abbr title=&#34;Public Key Infrastructure&#34;&gt;PKI&lt;/abbr&gt; also include IP addresses and &lt;code&gt;.onion&lt;/code&gt; addresses, but most &lt;abbr&gt;CAs&lt;/abbr&gt; don&amp;rsquo;t offer free certificates for those.&amp;#160;&lt;a href=&#34;#fnref:21&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:22&#34;&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://blog.cloudflare.com/keyless-delegation/&#34;&gt;Delegated Credentials for &lt;abbr&gt;TLS&lt;/abbr&gt;&lt;/a&gt;&lt;/cite&gt; on &lt;span&gt;The Cloudflare Blog&lt;/span&gt;&lt;/span&gt; describes this motivation in more detail. Essentially, a delegation credential gets rapidly pushed to the edge server. It represents an efficiency improvement over edge servers periodically requesting new certificates.&amp;#160;&lt;a href=&#34;#fnref:22&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:23&#34;&gt;
&lt;p&gt;I don&amp;rsquo;t recommend acme.sh. Sandboxing complex shell scripts proves difficult. acme.sh has had severe arbitrary remote-code-execution vulnerabilities exploited by a &lt;abbr&gt;CA&lt;/abbr&gt;: see &lt;a href=&#34;https://nvd.nist.gov/vuln/detail/CVE-2023-38198&#34;&gt;CVE-2023-38198&lt;/a&gt;. While acme.sh developers fixed the vulnerabilities, they revealed the difficulty of securing a complex shell script that handles untrusted content.&amp;#160;&lt;a href=&#34;#fnref:23&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Takeaways from the Google Content Warehouse API documentation leak</title>
      <link>https://envs.net/~seirdy/posts/2024/05/30/google-document-warehouse-api-docs-leak/</link>
      <pubDate>Thu, 30 May 2024 08:47:38 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2024/05/30/google-document-warehouse-api-docs-leak/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2024/05/30/google-document-warehouse-api-docs-leak/">&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;Introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In March, the official Elixir client for Google APIs &lt;a href=&#34;https://github.com/googleapis/elixir-google-api/commit/d7a637f4391b2174a2cf43ee11e6577a204a161e&#34;&gt;received an accidental commit for internal non-public APIs&lt;/a&gt;. The commit added support for Google&amp;rsquo;s Content Warehouse API, which includes Google&amp;rsquo;s 14,000+ search ranking factors. Oops! Some people noticed this after its redaction earlier this month, and the news broke on May 28. You can read through the &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/api-reference.html&#34;&gt;Content Warehouse API reference on HexDocs&lt;/a&gt;. I skimmed through these and read some blog posts by others who looked more deeply.&lt;/p&gt;
&lt;p&gt;In particular, I referenced &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://ipullrank.com/google-algo-leak&#34;&gt;Secrets from the Algorithm: Google Search’s Internal Engineering Documentation Has Leaked&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://ipullrank.com/author/ipullrank&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Mike&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;King&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;. Note that Mike King&amp;rsquo;s article doubles as an advertisement for his company&amp;rsquo;s services and for the legitimacy of search engine optimization (&lt;abbr&gt;SEO&lt;/abbr&gt;) companies in general. I don&amp;rsquo;t endorse that message. I disagree with some of its claims, and elaborate on them in the coming sections. That said, I found the article well-researched. It cross-references information against other leaks, too.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;thoughts-on-individual-ranking-factors&#34;&gt;Thoughts on individual ranking factors&lt;/h2&gt;
&lt;p&gt;Google has over 14,000 ranking factors. I have not and will not read them all. I went through what other bloggers found notable, the &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.PerDocData.html&#34;&gt;&lt;code&gt;PerDocData&lt;/code&gt; page&lt;/a&gt;, and what looked interesting when I searched for keywords I thought would reveal important ranking factors.&lt;/p&gt;
&lt;h3 id=&#34;small-personal-sites-and-commercial-sites&#34;&gt;Small personal sites and commercial sites&lt;/h3&gt;
&lt;p&gt;Google determines if your site is a &lt;q cite=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.QualityNsrNsrData.html&#34;&gt;small personal site&lt;/q&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and calculates a &lt;code&gt;commercialScore&lt;/code&gt; in &lt;code&gt;PerDocData&lt;/code&gt; which &lt;q cite=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.PerDocData.html#module-attributes&#34;&gt;indicates [the] document is commercial (i.e. sells something)&lt;/q&gt;. The docs have no information about whether either signal is positive or negative. Given how Google results look today and the language it uses in its documentation for manual reviewers,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; I conclude that personal sites don&amp;rsquo;t receive a significant boost. If anything, they may be demoted instead.&lt;/p&gt;
&lt;p&gt;I feel disappointed. I always considered the bias against small sites unintentionally emergent from them having no SEO budget. If a solution already exists, why doesn&amp;rsquo;t Google use it to even this gap? A more optimistic interpretation is that this factor will have weight when it&amp;rsquo;s ready and resistant to manipulation, but I don&amp;rsquo;t see incentives lining up to make that happen.&lt;/p&gt;
&lt;h3 id=&#34;font-size&#34;&gt;Font size‽&lt;/h3&gt;
&lt;p&gt;Google tracks &amp;ldquo;weighted font size&amp;rdquo; to notice key terms. Separation of content/semantics and form/presentation is baked into the DNA of the Web. Google should stick to semantic HTML elements such as &lt;code&gt;&amp;lt;dfn&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;dt&amp;gt;&lt;/code&gt;, or at &lt;em&gt;least&lt;/em&gt; &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I worry that people will interpret this piece of API documentation as advice and run with it. &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/notes/2022/08/02/accessibility-and-search-indexes/&#34;&gt;Search engines have the power to incentivize good behavior&lt;/a&gt;, and this piece of information has the opposite effect. Visual emphasis should derive from semantic meaning, dammit!&lt;/p&gt;
&lt;p&gt;This might have no weight in production. Perhaps Google uses the font size factor during A/B testing, comparing how results change when considering both styling and semantics. Google &lt;em&gt;tracking&lt;/em&gt; something isn&amp;rsquo;t evidence that Google uses it in production. &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.GoodocFontSizeStats.html&#34;&gt;A closer read of the docs shows Google tracking ten font metrics&lt;/a&gt;, and I don&amp;rsquo;t believe that attributes such as &lt;code&gt;medianLineSpan&lt;/code&gt; and &lt;code&gt;fontId&lt;/code&gt; are ranking factors. It&amp;rsquo;s still plausible that font size impacts ranking since Google does track font size separately as an attribute of anchor text.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;chrome-user-data&#34;&gt;Chrome user data&lt;/h3&gt;
&lt;p&gt;Google uses Chrome and click data, much like how Brave Search uses Brave data.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; I don&amp;rsquo;t like this, as it lends itself to clickbait and chasing engagement rather than actual quality. At least, unlike Brave, Google doesn&amp;rsquo;t measure clicks on &lt;em&gt;competitor engines.&lt;/em&gt; This contradicts &lt;em&gt;many&lt;/em&gt; official docs and spokespeople. I would put a disclaimer like the one in the earlier section, but Mike King cross-referenced this against other leaks that confirm as much. Plausible deniability seems low.&lt;/p&gt;
&lt;h3 id=&#34;manual-review&#34;&gt;Manual review&lt;/h3&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;golden&lt;/code&gt; (type: &lt;code&gt;boolean()&lt;/code&gt;, default: &lt;code&gt;nil&lt;/code&gt;) - Flag for indicating that the document is a gold-standard document. This can be used for putting additional weight on human-labeled documents in contrast to automatically labeled annotations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.NlpSaftDocument.html#module-attributes&#34;&gt;Google Content Warehouse API documentation: GoogleApi.ContentWarehouse.V1.Model.NlpSaftDocument&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The existence of manual review to evaluate Google&amp;rsquo;s ranking has never been secret, but evidence that manually reviewed documents can have a ranking adjustment is new.&lt;/p&gt;
&lt;p&gt;Manual ranking can combine with modifications to your ranking algorithm to bias your centrality algorithm around handpicked pages, which is how Marginalia achieves its anti-SEO bias.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; Personalized PageRank is one such algorithm, documented in the original PageRank paper. I like the use of manual review for &amp;ldquo;gold-standard documents&amp;rdquo; when applied to centrality algorithm biasing. However, I don&amp;rsquo;t know how I feel about manual reviewer scores directly appearing as a result ranking factor.&lt;/p&gt;
&lt;p&gt;Like font size, we don&amp;rsquo;t know whether Google actually uses manual review in production ranking factors. Google might catalog it here to run tests of expected-versus-actual ranking. Directly or indirectly, it shows that Google does take manual reviews into account in some way.&lt;/p&gt;
&lt;h3 id=&#34;bias-against-new-sites&#34;&gt;Bias against new sites&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s not just you. Google has a bias against new sites due to their spam potential.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; Contrary to what official statements say, Google has a &amp;ldquo;sandbox&amp;rdquo; for new sites. Google also uses domain registration information.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; Mike King&amp;rsquo;s post says this comes from Google Domains itself, but I haven&amp;rsquo;t found evidence to back this up. Current domain registration records are public. An organization such as Google can use them to build a catalog of historical registration information without tapping into its domain registry. Anybody with &lt;code&gt;whois&lt;/code&gt; can do this!&lt;/p&gt;
&lt;h3 id=&#34;truncation&#34;&gt;Truncation&lt;/h3&gt;
&lt;p&gt;Google does truncate pages to a certain number of tokens,&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; like most engines, instead of reading long pages indefinitely. I find this strange: based on keyword matches, I&amp;rsquo;m sure Google has read to the end of some of my longest blog posts. Some fill almost 100 pages printed out (yeah…I have a problem). Google uses a limited number of historic versions of pages,&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; so this isn&amp;rsquo;t due to historical versions of my page. Perhaps the token limit is just that high.&lt;/p&gt;
&lt;h3 id=&#34;author-name-mismatches&#34;&gt;Author name mismatches&lt;/h3&gt;
&lt;p&gt;Google extracts the same piece of metadata (e.g., published/updated timestamps or author names) from wherever it exists (the URL, byline, natural-language processing, structured data, the sitemap, etc.). For authors, it does seem to care about mismatches. Public documentation allows an author entity to have many names, and this factor doesn&amp;rsquo;t necessarily contradict that. I imagine that ensuring author name consistency could create bias against people who do specify different authors in different parts of the same page (plural systems come to mind), especially when we consider false positives. I&amp;rsquo;m uncertain; this is speculation on my part.&lt;/p&gt;
&lt;h2 id=&#34;a-cold-shower-this-isnt-as-significant-as-some-seos-claim&#34;&gt;A cold shower: this isn&amp;rsquo;t as significant as some SEOs claim&lt;/h2&gt;
&lt;p&gt;We only have API documentation. We don&amp;rsquo;t know about any hidden knowledge, whether any of these factors have a ranking weight of &amp;ldquo;zero&amp;rdquo;, whether any of these conditionally apply, which are only used internally for testing, etc. As I said in prior disclaimers, some factors might exist for testing purposes. Serious conclusions drawn from this leak are, to some degree, speculation.&lt;/p&gt;
&lt;p&gt;I wouldn&amp;rsquo;t panic over how SEO companies use this leak to game the algorithm and ruin search more. Given their track record of missing the forest for the trees and the ever-changing hidden weighting factors we can&amp;rsquo;t see, we have little reason for concern. I imagine certain people in the SEO industry jumping to conclusions based on word choice in these API docs, not realizing how words&amp;rsquo; original legacy meanings and current meanings are different.&lt;/p&gt;
&lt;p&gt;For example, per-page metadata includes integer attributes such as &lt;code&gt;crawlerPageRank&lt;/code&gt; and &lt;code&gt;pagerank2&lt;/code&gt;, but PageRank is no longer a useful way to build a ranking algorithm for the entire Web. The attribute might no longer carry weight, or the decades-old PageRank centrality algorithm might not populate this anymore. To put this in perspective, the docs mention a &lt;code&gt;HtmlrenderWebkitHeadlessProto&lt;/code&gt; but Google&amp;rsquo;s known to use a Chromium-based browser to render pages. Chromium hasn&amp;rsquo;t used WebKit in a decade; it hard-forked WebKit to make Blink in 2013.&lt;/p&gt;
&lt;p&gt;Per-page metadata also includes a &lt;code&gt;toolbarPagerank&lt;/code&gt; integer attribute that hearkens back to the ancient Toolbar PageRank; this also probably doesn&amp;rsquo;t carry weight today. You can read more about Google&amp;rsquo;s use of PageRank and Toolbar in &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://searchengineland.com/rip-google-pagerank-retrospective-244286&#34;&gt;RIP Google PageRank score: A retrospective on how it ruined the web&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://dannysullivan.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Danny&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Sullivan&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;section role=&#34;doc-conclusion&#34;&gt;
&lt;h2 id=&#34;conclusion-my-takeaways&#34;&gt;Conclusion: my takeaways&lt;/h2&gt;
&lt;p&gt;I still despise how the SEO industry and Google have started an arms race to incentivize making websites worse for actual users, selecting against small independent websites. I do maintain that we can carve out a non-toxic sliver of SEO: &amp;ldquo;search engine compatibility&amp;rdquo;. Few features uniquely belong in search engine, browser, reading mode, feed reader, social media link-preview, etc. compatibility. If you specifically ignore search engine compatibility but target everything else, you&amp;rsquo;ll implement it regardless. &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/notes/2022/06/23/agent-optimization/&#34;&gt;I call this principle &lt;dfn&gt;&amp;ldquo;agent optimization&amp;rdquo;&lt;/dfn&gt;&lt;/a&gt;. I prefer the idea of optimizing for generic agents to optimizing for search engines, let alone one (1) search engine, in isolation. Naturally, user-agents (including browsers) come first; nothing should have significant conflict with them.&lt;/p&gt;
&lt;p&gt;If you came to this article as an SEO, I don&amp;rsquo;t think I can convince you to stop. Instead, remember that it&amp;rsquo;s easy to miss the forest for the trees. Don&amp;rsquo;t lose sleep over &lt;em&gt;one in fourteen thousand ranking criteria&lt;/em&gt; without other data backing up its importance and current relevance.&lt;/p&gt;
&lt;p&gt;Consider my rule of thumb, whose relevance will outlast this leak: assume Google looks at whatever information it can &lt;em&gt;if it helps Google draw the conclusions its public guidelines say it tries to draw,&lt;/em&gt; even if those guidelines say it doesn&amp;rsquo;t use that information. The information Google uses differs from what it tells the public (yes, Google lied), and changes with time; however, Google&amp;rsquo;s intent makes for less of a moving target. This leak might contradict &lt;em&gt;how&lt;/em&gt; Google determines what it should rank well, but not &lt;em&gt;what&lt;/em&gt; it looks for. A good reference for what Google looks for is &lt;a href=&#34;https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf&#34;&gt;Google&amp;rsquo;s search rater guidelines&lt;/a&gt; for manual reviewers.&lt;/p&gt;
&lt;p&gt;Google lied, but don&amp;rsquo;t uncritically fall for the coming SEO hype.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.QualityNsrNsrData.html&#34;&gt;the &lt;code&gt;smallPersonalSite&lt;/code&gt; attribute of &lt;code&gt;QualityNsrNsrData&lt;/code&gt;&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;See the conclusion, or snippets of the Google Search Central documentation &lt;a href=&#34;https://developers.google.com/search/docs/fundamentals/creating-helpful-content&#34;&gt;such as this page describing the &lt;abbr&gt;EEAT&lt;/abbr&gt; principle: experience, expertise, authoritativeness, and trustworthiness&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.AnchorsAnchor.html#module-attributes&#34;&gt;&lt;code&gt;AnchorsAnchor&lt;/code&gt; has a &lt;code&gt;fontSize&lt;/code&gt; member&lt;/a&gt; with no extra documentation.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;I&amp;rsquo;d always assumed (in private, due to a lack of evidence) that the Chrome User Experience Report (&lt;abbr&gt;CrUX&lt;/abbr&gt;) played a role in search rankings. I don&amp;rsquo;t know if or how this data overlaps with CrUX.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.marginalia.nu/log/26-personalized-pagerank/&#34;&gt;The creator of Marginalia documents initial experiments in a 2021 blog post&lt;/a&gt;, and later &lt;a href=&#34;https://news.ycombinator.com/item?id=32349094&#34;&gt;confirmed this on &amp;ldquo;Hacker&amp;rdquo; &amp;ldquo;News&amp;rdquo;&lt;/a&gt;. In 2023, &lt;a href=&#34;https://www.marginalia.nu/log/73-new-approach-to-ranking/&#34;&gt;Marginalia switched away from PageRank to a different centrality algorithm&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.PerDocData.html#module-attributes&#34;&gt;the &lt;code&gt;hostAge&lt;/code&gt; attribute of &lt;code&gt;PerDocData&lt;/code&gt;&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.RegistrationInfo.html&#34;&gt;&lt;code&gt;RegistrationInfo&lt;/code&gt;&lt;/a&gt;. It defines &lt;code&gt;createdDate&lt;/code&gt; and &lt;code&gt;expiredDate&lt;/code&gt; attributes.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;See docs for &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.PerDocData.html#module-attributes&#34;&gt;&lt;code&gt;numTokens&lt;/code&gt; in &lt;code&gt;DocProperties&lt;/code&gt;&lt;/a&gt;: &lt;q cite=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.DocProperties.html#module-attributes&#34;&gt;we drop some tokens in mustang and also truncate docs at a max cap&lt;/q&gt;.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://hexdocs.pm/google_api_content_warehouse/0.4.0/GoogleApi.ContentWarehouse.V1.Model.CompositeDocIndexingInfo.html#module-attributes&#34;&gt;the &lt;code&gt;urlHistory&lt;/code&gt; attribute of &lt;code&gt;CompositeDocIndexingInfo&lt;/code&gt;&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>MDN’s AI Help and lucid lies</title>
      <link>https://envs.net/~seirdy/posts/2024/04/04/mdn-ai-help-and-lucid-lies/</link>
      <pubDate>Thu, 04 Apr 2024 23:15:54 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2024/04/04/mdn-ai-help-and-lucid-lies/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2024/04/04/mdn-ai-help-and-lucid-lies/">&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Following the release of MDN&amp;rsquo;s AI chatbot &amp;ldquo;feature&amp;rdquo;, many developers &lt;a href=&#34;https://github.com/mdn/yari/issues/9230&#34;&gt;turned to GitHub Issues to voice concerns&lt;/a&gt;. Most concerns revolved around the chatbot spouting misinformation on a technical reference expected to contain accurate information, and ethical concerns related to OpenAI and the use of a large language model (&lt;abbr&gt;LLM&lt;/abbr&gt;).&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t find the mere existence of LLM dishonesty to be worth blogging about; it&amp;rsquo;s already well-established. Let&amp;rsquo;s instead explore one of the inescapable roots of this dishonesty: LLMs exacerbate biases already present in their training data and fail to distinguish between unrelated concepts, creating lucid lies.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A &lt;dfn&gt;lucid lie&lt;/dfn&gt; is a lie that, unlike a hallucination, can be traced directly to content in training data uncritically absorbed by a large language model. MDN&amp;rsquo;s AI Help is the perfect example.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;conflating-common-and-uncommon-angles&#34;&gt;Conflating common and uncommon angles&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;AI Help&amp;rdquo; answers usually apply to the common case at the expense of a less-common case, even when asked about the less-common case. One of many examples is horrible accessibility advice.&lt;/p&gt;
&lt;h3 id=&#34;example-assistive-technology-performance-tips&#34;&gt;Example: assistive technology performance tips&lt;/h3&gt;
&lt;p&gt;Ask the chatbot about a performance technique&amp;rsquo;s applicability to assistive technology (&lt;abbr&gt;AT&lt;/abbr&gt;), and it&amp;rsquo;ll give you advice on performance related to graphical rendering while passing it off as improving &lt;abbr&gt;AT&lt;/abbr&gt; performance. For example: I often work with large &lt;abbr title=&#34;Document Object Model&#34;&gt;DOM&lt;/abbr&gt; sizes, which can be a performance challenge for &lt;abbr&gt;AT&lt;/abbr&gt; such as screen- and braille-readers which struggle to handle large accessibility trees.&lt;/p&gt;
&lt;p&gt;At one point, I wanted to use &lt;code&gt;content-visibility&lt;/code&gt; to improve large-&lt;abbr&gt;DOM&lt;/abbr&gt; performance. Until later, I didn&amp;rsquo;t realize that its relevance to the accessibility tree was so different from its relevance to rendering performance. Here is one answer to the question &lt;q&gt;I have many &lt;abbr&gt;DOM&lt;/abbr&gt; nodes. How can I improve &lt;abbr&gt;AT&lt;/abbr&gt; performance using content-visibility?&lt;/q&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To improve accessibility tree (AT) performance using content-visibility, you can utilize the &lt;code&gt;content-visibility: auto&lt;/code&gt; property. This property allows you to improve page performance without negatively impacting accessibility.&lt;/p&gt;
&lt;p&gt;When you apply &lt;code&gt;content-visibility: auto&lt;/code&gt; to off-screen content, it remains in the document object model (&lt;abbr&gt;DOM&lt;/abbr&gt;) and the accessibility tree. This means that the content is still accessible to assistive technologies, but the styles for off-screen content are not rendered. However, it’s important to note that elements intentionally hidden with &lt;code&gt;display: none&lt;/code&gt; or &lt;code&gt;visibility: hidden&lt;/code&gt; will still appear in the accessibility tree.&lt;/p&gt;
&lt;p&gt;If you want to prevent an element from appearing in the accessibility tree, you can use the &lt;code&gt;aria-hidden=&amp;quot;true&amp;quot;&lt;/code&gt; attribute.&lt;/p&gt;
&lt;p&gt;Here’s an example of using &lt;code&gt;content-visibility: auto&lt;/code&gt; to improve rendering cost for long pages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the section elements have &lt;code&gt;content-visibility: auto&lt;/code&gt; applied to them. This allows the user agent to skip rendering work (including layout and painting) for off-screen sections until they come close to the viewport. By skipping the rendering work, the initial page load becomes faster, improving performance.&lt;!--`--&gt;&lt;/p&gt;
&lt;p&gt;Remember, &lt;code&gt;content-visibility: auto&lt;/code&gt; helps optimize rendering and layout, but it’s important to ensure that your content remains accessible to all users.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are multiple inaccuracies present,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; but I&amp;rsquo;ll focus on a glaring one:&lt;/p&gt;
&lt;p&gt;This response &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility&#34;&gt;cites an MDN page that contradicts the given advice&lt;/a&gt;. While &lt;code&gt;content-visibility: auto&lt;/code&gt; &lt;em&gt;does&lt;/em&gt; improve graphical rendering by deferring off-screen rendering, this has no impact on the accessibility tree: off-screen content is still accessible to &lt;abbr&gt;AT&lt;/abbr&gt; (assistive technology, not accessibility tree), find-in-page, etc. Only rendering is deferred.&lt;/p&gt;
&lt;p&gt;The assistive technology implications are an afterthought that don&amp;rsquo;t get equal treatment alongside graphical rendering concerns. Regardless of your thoughts on said treatment: here we see that bias amplified, resulting in misinformation and disability erasure.&lt;/p&gt;
&lt;h2 id=&#34;conflating-broad-and-specific-questions&#34;&gt;Conflating broad and specific questions&lt;/h2&gt;
&lt;p&gt;Broad questions already tend to have more documentation than specific questions. Trained on this understandably biased documentation, AI Help tends to fall flat when asked for any overly specific advice.&lt;/p&gt;
&lt;h3 id=&#34;example-asking-about-specific-page-speed-metrics&#34;&gt;Example: asking about specific page speed metrics&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s easier to find generic advice on improving load times than it is to find advice on improving specific &lt;em&gt;aspects&lt;/em&gt; of load times. AI Help conflates the two, offering incorrect advice for improving a given metric.&lt;/p&gt;
&lt;p&gt;Say you run a page speed benchmark using your favorite website speed test,&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and find out that your performance is excellent across the board &lt;em&gt;except&lt;/em&gt; for the Time to First Byte (&lt;abbr&gt;TTFB&lt;/abbr&gt;). A natural follow-up question would be: &lt;q&gt;How do I reduce my &lt;abbr&gt;TTFB&lt;/abbr&gt;?&lt;/q&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how AI Help answers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To reduce your page&amp;rsquo;s Time to First Byte (TTFB), which is the time between the browser requesting a page and receiving the first byte of information from the server, you can implement several optimizations. Here are some strategies to improve TTFB:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optimize Server Response Time&lt;/strong&gt;: Ensure your server responds quickly to requests. This can be achieved by optimizing server-side code, database queries, and server configurations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use a Content Delivery Network (CDN)&lt;/strong&gt;: Utilize a CDN to cache and deliver content from servers closer to the user, reducing the physical distance and network latency.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Compression&lt;/strong&gt;: Compress resources like HTML, CSS, and JavaScript using techniques like GZIP or Brotli compression to reduce file sizes and improve transfer speeds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Minimize HTTP Requests&lt;/strong&gt;: Reduce the number of resources loaded on your page by combining files, using image sprites, and minimizing unnecessary requests.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Browser Caching&lt;/strong&gt;: Implement proper caching headers to allow browsers to store resources locally, reducing the need to fetch them again on subsequent visits.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optimize Images&lt;/strong&gt;: Compress and optimize images to reduce their file sizes without compromising quality. Consider lazy loading images to defer loading offscreen images.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduce Server-Side Processing&lt;/strong&gt;: Minimize server-side processing by caching dynamic content, optimizing database queries, and using efficient algorithms.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By implementing these strategies, you can help reduce your page&amp;rsquo;s TTFB and improve overall performance. For more detailed information and best practices, you can refer to the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Performance&#34;&gt;Performance best practices&lt;/a&gt; documentation on MDN.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this situation, &lt;abbr title=&#34;Time to First Byte&#34;&gt;TTFB&lt;/abbr&gt; is the bottleneck. Any advice concerning different aspect of page speed optimization would encourage premature optimization. Despite the question specifically asking about &lt;abbr&gt;TTFB&lt;/abbr&gt;, we&amp;rsquo;ve received plenty of performance advice that has nothing to do with it: A page&amp;rsquo;s &lt;abbr&gt;TTFB&lt;/abbr&gt; only describes the time spent waiting for the initial byte of a response. The number of subsequent requests and the size of the requests have no impact on it. Points 3 and 6 are premature optimizations; point 5 is a partial workaround but not really an answer.&lt;/p&gt;
&lt;h2 id=&#34;blurring-the-lines-classifying-llm-lies&#34;&gt;Blurring the lines classifying LLM lies&lt;/h2&gt;
&lt;p&gt;Sometimes the boundary between specific/general mislabeling, conflation of overlapping topics, and hallucination isn&amp;rsquo;t so clear. Let&amp;rsquo;s look at an example of an LLM blurring the lines between all three.&lt;/p&gt;
&lt;h3 id=&#34;combined-example-specific-information-conflation-and-hallucination&#34;&gt;Combined example: specific information, conflation, and hallucination.&lt;/h3&gt;
&lt;p&gt;I did some research before enabling a TLS feature called Zero Round Trip Time (&lt;abbr&gt;0-RTT&lt;/abbr&gt;) on my &lt;code&gt;seirdy.one&lt;/code&gt; domain, to make sure it was safe to do so given &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc8446#appendix-E.5&#34;&gt;0-RTT&amp;rsquo;s susceptibility to replay attacks&lt;/a&gt;. I moved anything vulnerable to replay attacks to alternate domains.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; I wanted to know the answer to the question: &lt;q&gt;What are the security implications of 0-RTT on a static site?&lt;/q&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what AI Help had to say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;0-RTT (Zero Round Trip Time) is a feature of the Transport Layer Security (TLS) protocol that allows a client to send data to the server in the first message of the TLS handshake, reducing latency. However, there are security implications to consider when using 0-RTT, especially on a static site. When it comes to a static site, where content does not change frequently and interactions are limited, using 0-RTT can introduce potential security risks. Since 0-RTT data is sent before the server&amp;rsquo;s response, it can be replayed by an attacker. This means that if sensitive data is transmitted in the 0-RTT data, it could be intercepted and replayed by an attacker to impersonate the client. To mitigate these security risks on a static site using 0-RTT, it&amp;rsquo;s important to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Avoid sending sensitive data in 0-RTT messages: Ensure that any data sent in the 0-RTT phase is non-sensitive and does not pose a security risk if intercepted and replayed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implement additional security measures: Consider implementing additional security measures such as encryption, authentication mechanisms, and data validation to protect against replay attacks and unauthorized access.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Regularly review and update security practices: Stay informed about the latest security best practices and updates related to 0-RTT and TLS to ensure that your static site remains secure. For more detailed information on 0-RTT and its security implications, you can refer to the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security&#34;&gt;TLS 1.3 specification&lt;/a&gt; on MDN.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the most clear-cut lie that MDN&amp;rsquo;s AI Help has told me so far. Static sites represent some of the safest uses of 0-RTT, without any extra backend protections: replaying a request for a static asset doesn&amp;rsquo;t help an attacker until we introduce other complexities to our backend.&lt;/p&gt;
&lt;p&gt;On MDN and the Web in general, advice on 0-RTT tends to be general to all sites, or apply to common CMS platforms; little applies specifically to static sites. MDN gave us generic advice that only applies to a complex CMS when asked specifically about static sites.&lt;/p&gt;
&lt;p&gt;This is also partly a hallucination: MDN has no documentation on what a replay attack &lt;em&gt;is,&lt;/em&gt; or how to defend against it. AI Help made up vague defenses such as &amp;ldquo;encryption&amp;rdquo; and &amp;ldquo;authentication&amp;rdquo;, even though this is a weakness &lt;em&gt;in&lt;/em&gt; authenticated encryption protocols. These are valid defenses on their own, but have nothing to do with the question asked.&lt;/p&gt;
&lt;p&gt;An LLM may be able to answer simpler questions, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;q&gt;What is a static site?&lt;/q&gt;&lt;/li&gt;
&lt;li&gt;&lt;q&gt;Are static sites vulnerable to replay attacks?&lt;/q&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The ability to answer such questions isn&amp;rsquo;t unique. Asking a chatroom, a forum, or even a link-and-summary search engine should pull up useful information.&lt;/p&gt;
&lt;p&gt;An LLM cannot be trusted to synthesize different concepts without conflating them, or to switch from broad to specific concepts. Pseudo-hallucinations fill the gap.&lt;/p&gt;
&lt;section role=&#34;doc-conclusion&#34;&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;h3 id=&#34;conclusions-about-mdns-ai-help&#34;&gt;Conclusions about MDN&amp;rsquo;s AI Help&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve provided examples of uncommon angles and specific topics that cause MDN&amp;rsquo;s AI Help to lie.&lt;/p&gt;
&lt;p&gt;The Mozilla Blog post &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://blog.mozilla.org/en/products/mdn/responsibly-empowering-developers-with-ai-on-mdn/&#34;&gt;Responsibly empowering developers with AI on MDN&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; highlighted positive quantitative feedback for AI Help. &lt;strong&gt;Positive perceived helpfulness needs to be multiplied by actual helpfulness&lt;/strong&gt; before it&amp;rsquo;s taken into account; in this case, I argue that &lt;strong&gt;actual helpfulness is negative.&lt;/strong&gt; A user unfamiliar with &lt;code&gt;content-visibility&lt;/code&gt; (such as a past version of myself) or &lt;abbr&gt;TTFB&lt;/abbr&gt; only reinforces the harmfulness of such a tool by marking these answers as &amp;ldquo;helpful&amp;rdquo;. The high perceived helpfulness counts against this feature&amp;rsquo;s merit.&lt;/p&gt;
&lt;p&gt;Not everything should optimize for engagement. Engagement multiplies harms.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;A recurring complaint we heard from our readers was that MDN is excellent when you know what to look for. If you don&amp;rsquo;t, it&amp;rsquo;s not easy to discover the information you need&amp;hellip;Developers with less experience find it harder to navigate through MDN&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://developer.mozilla.org/en-US/blog/ai-explain-postmortem/&#34;&gt;Reflections on AI Explain: A postmortem&lt;/a&gt;&lt;/cite&gt;, by &lt;span&gt;&lt;span&gt;the MDN Team&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If all web development questions were easy to answer by browsing MDN, this tool wouldn&amp;rsquo;t be necessary. Uncommon and specific questions are &lt;strong&gt;the hardest questions to answer without expert assistance.&lt;/strong&gt; A tool designed to answer hard questions that is &lt;em&gt;so likely to fail under these conditions&lt;/em&gt; is worse than no tool all.&lt;/p&gt;
&lt;p&gt;I do like the tool&amp;rsquo;s ability to suggest links to relevant MDN pages. Perhaps it could power improvements to MDN search&amp;rsquo;s result ranking, or suggest keywords for future searches.&lt;/p&gt;
&lt;h3 id=&#34;implications-for-llms-as-a-whole&#34;&gt;Implications for LLMs as a whole&lt;/h3&gt;
&lt;p&gt;Some topics get written about more than others. Our society disproportionately incentivizes generic, far-reaching, easy-to-create, and profitable content. I don&amp;rsquo;t think it&amp;rsquo;s currently possible to source nontrivial training data without biases. More importantly: I&amp;rsquo;m skeptical that such an impossibly comprehensive data set would eliminate the conflations I described in this article. Tripping over bias to fall into a lucid lie is one of a range of symptoms of an inability to actually think.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;The model, &lt;i&gt;per se,&lt;/i&gt; doesn&amp;rsquo;t exist until after the training process is completed, and has no ability to make such decisions at all. It bases its statistical model of language on the entirety of the training data with no discrimination, except maybe a little outlier exclusion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://www.alm.website/me&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Athena Martin&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; in a &lt;cite class=&#34;p-name&#34;&gt;Fediverse DM&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Current LLMs can&amp;rsquo;t critically examine training data and its biases. For humans, such critical analysis is often difficult; for machines, it&amp;rsquo;s &lt;strong&gt;currently impossible.&lt;/strong&gt; Until we make such a breakthrough, LLMs can never be remotely honest. Nobody should consider deploying an LLM to perform a role that demands significant accountability. Answering questions honestly and accurately demands accountability for dishonest and inaccurate answers, so this responsibility shouldn&amp;rsquo;t fall to LLM. To market an LLM as capable of answering questions reflects dishonesty or ignorance; neither inspires trust. Hallucinations are one thing, but miscategorizing facts due to an inability to critically analyze biases and topic relations in training data is something that no amount of reinforcement learning will fix. These are lucid lies.&lt;/p&gt;
&lt;p&gt;This article on AI focused on the inherent untrustworthiness of LLMs. Stay tuned for a follow-up article about AI that focuses on data-scraping and the theory of labor. It&amp;rsquo;ll examine what makes many forms of generative AI ethically problematic, and the constraints employed by more ethical forms. I&amp;rsquo;ll edit this paragraph with a link to the follow-up post when it&amp;rsquo;s ready.&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&#34;doc-acknowledgments&#34;&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://www.alm.website/me&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Athena Martin&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for providing feedback on an initial draft. She helped me better communicate the idea that LLMs are statistical models, not thinking machines. With her permission, I borrowed a quote from her feedback to use in my conclusion.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://uni.horse/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Emily&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for highlighting that biased data isn&amp;rsquo;t the root of the issue; the issue is an LLM&amp;rsquo;s inability to think. I agreed, and reworded (and re-titled) much of this article in response.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I use the term &amp;ldquo;lie&amp;rdquo; instead of hallucination because it&amp;rsquo;s broad. A hallucination is merely one type of lie. LLMs may lie in any way a human can. Lies by omission are the first non-hallucinatory lie that comes to mind. I exhausted other terms: calling them &amp;ldquo;misunderstandings&amp;rdquo; implies that LLMs have the capacity to understand things; calling them &amp;ldquo;bugs&amp;rdquo; implies that this is due to a programming error; calling them &amp;ldquo;accidents&amp;rdquo; implies that this isn&amp;rsquo;t expected behavior (this article shows why it should be). Telling a lie does not require understanding; repeating one does not require intent.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Another inaccuracy: while it&amp;rsquo;s not standard behavior, many browsers do exclude content from the accessibility tree in response to certain &lt;code&gt;display&lt;/code&gt; properties, including &lt;code&gt;display: none&lt;/code&gt;. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://adrianroselli.com/2022/07/its-mid-2022-and-browsers-mostly-safari-still-break-accessibility-via-display-properties.html&#34;&gt;It’s Mid-2022 and Browsers (Mostly Safari) Still Break Accessibility via Display Properties&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://adrianroselli.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Adrian&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Roselli&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; covers this in more detail.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;I recommend Chromium&amp;rsquo;s Lighthouse for simple measurements, and the Firefox Performance Monitor for detailed analysis. Plenty of tools exist between those extremes.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;This included my Webmention collector and my CSP-report collector (only used on my staging site and a dedicated CSP debugging page), which I moved to &lt;code&gt;collector.seirdy.one&lt;/code&gt;. All that&amp;rsquo;s left here is a static site, Libravatar endpoint (implemented in Nginx configs), single-user WebFinger endpoint (implemented with Nginx configs), Webmention endpoint, and a not-so-secret DNS resolver&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Proposal: an HTML element for spoilers</title>
      <link>https://envs.net/~seirdy/posts/2023/11/12/spoiler-element/</link>
      <pubDate>Sun, 12 Nov 2023 21:48:00 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2023/11/12/spoiler-element/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2023/11/12/spoiler-element/">&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;figure&gt;
&lt;blockquote role=&#34;doc-epigraph&#34;&gt;
&lt;p&gt;I wish it were possible to look up any medical issue without being exposed to the most graphic photographs ever taken by man or beast.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://velveteen.one/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Velveteen&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://akko.wtf/objects/8fd2f79b-9529-441d-8b6f-079ac4a8f599&#34;&gt;Post on akko.wtf&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;While browsing the &lt;abbr title=&#34;Web Incubator Community Group&#34;&gt;WICG&lt;/abbr&gt; discussion forms, I stumbled upon &lt;a href=&#34;https://discourse.wicg.io/t/standardized-spoiler-tag/5814&#34;&gt;a proposal for a standardized &lt;code&gt;&amp;lt;spoiler&amp;gt;&lt;/code&gt; element in HTML5&lt;/a&gt;. I made two comments, and stopped myself before writing a third; this called for a blog post. &lt;em&gt;I think HTML should have a spoiler element.&lt;/em&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#introduction&#34;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#prior-art&#34;&gt;Prior art&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#comparison-with-details&#34;&gt;Comparison with &lt;code&gt;details&lt;/code&gt;&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#semantics&#34;&gt;Semantics&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#behavior&#34;&gt;Behavior&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#presentation&#34;&gt;Presentation&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#use-cases&#34;&gt;Use-cases&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#potential-attributes&#34;&gt;Potential attributes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#considerations&#34;&gt;Considerations&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#considerations-for-user-agents&#34;&gt;Considerations for user-agents&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#considerations-for-authors&#34;&gt;Considerations for authors&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#privacy-considerations&#34;&gt;Privacy considerations&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#further-work&#34;&gt;Further work&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#snarky-thoughts-conflicts-of-interests&#34;&gt;Snarky thoughts: conflicts of interests&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;section&gt;
&lt;h2 id=&#34;prior-art&#34;&gt;Prior art&lt;/h2&gt;
&lt;p&gt;Spoilers are already implemented in several places around the Web, but without a standard set of semantics.&lt;/p&gt;
&lt;p&gt;A useful reference is the markup used in the Matrix protocol. Matrix messages may include a standardized subset of HTML, with some additional features provided by HTML attributes.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
&lt;figcaption id=&#34;code-3-caption&#34;&gt;
	&lt;span id=&#34;code-3&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 3&lt;/strong&gt; (&lt;span&gt;HTML&lt;/span&gt;)&lt;/span&gt;:
The following syntax creates a spoiler in Matrix:
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span data-mx-spoiler=&amp;quot;optional placeholder text&amp;quot;&amp;gt;hidden content&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;figure id=&#34;spoiler-matrix&#34; tabindex=&#34;-1&#34;&gt;
&lt;figcaption&gt;
&lt;p&gt;A screenshot of how Element, a Matrix client, renders a spoiler element:&lt;/p&gt;
&lt;/figcaption&gt;
&lt;picture&gt;&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler_dark.3702457077.jxl&#34;
		type=&#34;image/jxl&#34;
		media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler_dark.799828638.webp&#34;
		type=&#34;image/webp&#34;
		media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler_dark.3457637173.png&#34;
		type=&#34;image/png&#34;
		media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler.2892636637.webp&#34;
		type=&#34;image/webp&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler.2788064933.png&#34;
		type=&#34;image/png&#34; /&gt;
	&lt;img
		width=&#34;221&#34; height=&#34;64&#34;
		src=&#34;https://envs.net/~seirdy/p/spoiler.2788064933.png&#34; alt=&#34;screenshot of small faded text reading “optional placeholder text” followed by blurred regular text.&#34;
		
		decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;
&lt;/figure&gt;

&lt;p&gt;The visual result is typically the placeholder text followed by blurred or blacked-out hidden contents, revealed upon user interaction. Children aren&amp;rsquo;t limited to text; this is a common approach to hiding images.&lt;/p&gt;
&lt;figure id=&#34;spoiler-fedi&#34; tabindex=&#34;-1&#34;&gt;
&lt;figcaption&gt;
&lt;p&gt;An image marked sensitive on Firefish (a Fediverse server) shows a blurred placeholder. &lt;a href=&#34;https://pleroma.envs.net/notice/AZNKmYaNv9UOa9e3wO&#34;&gt;Original thread&lt;/a&gt;.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;picture&gt;&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler-fedi.3795827121.jxl&#34;
		type=&#34;image/jxl&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler-fedi.54977442.avif&#34;
		type=&#34;image/avif&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler-fedi.2205520329.webp&#34;
		type=&#34;image/webp&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/spoiler-fedi.88207012.jpg&#34;
		type=&#34;image/jpeg&#34; /&gt;
	&lt;img
		width=&#34;507&#34; height=&#34;485&#34;
		src=&#34;https://envs.net/~seirdy/p/spoiler-fedi.88207012.jpg&#34; alt=&#34;screenshot: a post by @freeplay@kitsunes.club shows a blurred image under placeholder text reading “NSFW: Click to show”.&#34;
		
		decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;
&lt;/figure&gt;


&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
&lt;figcaption id=&#34;code-4-caption&#34;&gt;
	&lt;span id=&#34;code-4&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 4&lt;/strong&gt;&lt;/span&gt;:
More special syntax for spoilers:
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;||optional placeholder text|Fluffychat and Discord hide this.||
&amp;gt;!Reddit hides this.!&amp;lt;
[spoiler=optional placeholder text]BBCode hides this[/spoiler]
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;p&gt;&lt;a href=&#34;https://www.bbcode.org/posting-a-spoiler-with-bbcode.php&#34;&gt;BBCode&lt;/a&gt; is the oldest example of dedicated spoiler syntax I know of.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 id=&#34;comparison-with-details&#34;&gt;Comparison with &lt;code&gt;details&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;On the &lt;abbr&gt;WICG&lt;/abbr&gt; forum, one user asked about the differences between &lt;code&gt;spoiler&lt;/code&gt; and &lt;code&gt;details&lt;/code&gt;. The two elements have very much in common; I&amp;rsquo;d even go so far as to say that &lt;code&gt;spoiler&lt;/code&gt; elements could also make use of &lt;code&gt;summary&lt;/code&gt; children for placeholder text.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; That being said, the semantics and behavior have important differences.&lt;/p&gt;
&lt;h3 id=&#34;semantics&#34;&gt;Semantics&lt;/h3&gt;
&lt;p&gt;While a disclosure widget exists to allow toggling information, a spoiler exists to make information &lt;em&gt;inaccessible without consent:&lt;/em&gt; invisible, inaudible, unreadable. A disclosure widget helps divert user&amp;rsquo;s attention away from hidden text; a spoiler protects users from hidden text.&lt;/p&gt;
&lt;p&gt;Following the examples in &lt;a href=&#34;#prior-art&#34;&gt;the &amp;ldquo;Prior Art&amp;rdquo; section&lt;/a&gt;, &lt;code&gt;summary&lt;/code&gt; can be an &lt;em&gt;optional&lt;/em&gt; first-child of a &lt;code&gt;spoiler&lt;/code&gt; while remaining a mandatory first-child of &lt;code&gt;details&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;behavior&#34;&gt;Behavior&lt;/h3&gt;
&lt;p&gt;Semantic differences should impact how activation works. Spoiler text should not be revealed until the placeholder text has been read. Unread spoiler text may include off-screen placeholders, placeholders that a screen/braille-reader hasn&amp;rsquo;t reached yet, and perhaps even spoiler text whose placeholders haven&amp;rsquo;t reached a magnifier&amp;rsquo;s viewport. Spoilers shouldn&amp;rsquo;t be revealed by accident.&lt;/p&gt;
&lt;p&gt;For visual users, placeholder text should be in the viewport for a minimum duration. A user-agent should expose a setting to increase this duration. Ideally, it could allow users to supply keywords for sensitive or non-sensitive topics for auto-hiding or auto-revealing spoilers. Spoiler text matching sensitive topics should require some form of additional confirmation.&lt;/p&gt;
&lt;p&gt;Functionality such as find-in-page may indicate a match obscured by a spoiler, but shouldn&amp;rsquo;t activate the spoiler. It may expand a disclosure widget.&lt;/p&gt;
&lt;h3 id=&#34;presentation&#34;&gt;Presentation&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;details&lt;/code&gt; is a block element; &lt;code&gt;spoiler&lt;/code&gt; can be either an inline or block element. A few words within a paragraph can be hidden behind a spoiler. &lt;code&gt;details&lt;/code&gt; tends to work more effectively on larger sections of content. A &lt;code&gt;spoiler&lt;/code&gt; should obscure content, but not the size of said content; it &lt;em&gt;obscures&lt;/em&gt; content without &lt;em&gt;removing&lt;/em&gt; it.&lt;/p&gt;
&lt;p&gt;For printouts, behavior should mirror &lt;code&gt;details&lt;/code&gt;. Print hidden if it&amp;rsquo;s hidden in the browser, and print revealed if it&amp;rsquo;s been revealed in the browser.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 id=&#34;use-cases&#34;&gt;Use-cases&lt;/h2&gt;
&lt;p&gt;Several overlapping use-cases exist:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Spoilers&amp;rdquo; for plot-twists. These are common on wikis such as TV Tropes.&lt;/li&gt;
&lt;li&gt;A warning for imagery that may be inappropriate in a public setting (you might want to hide erotic or gory content when you&amp;rsquo;re on the train).&lt;/li&gt;
&lt;li&gt;Content-warnings for potentially triggering topics.&lt;/li&gt;
&lt;li&gt;Hiding a joke&amp;rsquo;s punchline, or the answer to a riddle.&lt;/li&gt;
&lt;li&gt;Hiding user-generated content that&amp;rsquo;s been flagged by other users, awaiting moderation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could go on. This is an immensely useful feature that HTML doesn&amp;rsquo;t adequately address right now.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 id=&#34;potential-attributes&#34;&gt;Potential attributes&lt;/h2&gt;
&lt;p&gt;Some semantic configurability should be possible with HTML attributes:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;code&gt;preview&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;A boolean attribute for &lt;code&gt;spoiler&lt;/code&gt;. Hidden content could have a preview available or have no preview at all. A &amp;ldquo;true&amp;rdquo; value could show a partial preview of a sensitive image (e.g. a version with a reduced resolution and saturation, passed through a heavy blur filter); a &amp;ldquo;false&amp;rdquo; value could simply hide the content behind censor bars or filler content.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;preview-alt&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;An attribute for any element that supports the &lt;code&gt;alt&lt;/code&gt; attribute. This can supply alt-text for hidden versions of media without overly descriptive language, analogous to blurred or pixelated previews. &amp;ldquo;Black-and-white photo of a large wound&amp;rdquo; could be an image&amp;rsquo;s &amp;ldquo;preview-alt&amp;rdquo; text, while the actual alt text could describe the image more&amp;hellip;&lt;em&gt;vividly&lt;/em&gt;.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;loading&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;code&gt;img&lt;/code&gt;, &lt;code&gt;iframe&lt;/code&gt;, and other elements already support &lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; to enable native lazy loading. &lt;a href=&#34;https://discourse.wicg.io/t/add-loading-lazy-attribute-to-details-element/6060&#34;&gt;A thread on the WICG forums&lt;/a&gt; proposes allowing the attribute on container elements to apply to their children, singling out &lt;code&gt;details&lt;/code&gt; in particular. As &lt;code&gt;spoiler&lt;/code&gt; hides content, hidden children may have loading deferred until their parent &lt;code&gt;spoiler&lt;/code&gt; element activates.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 id=&#34;considerations&#34;&gt;Considerations&lt;/h2&gt;
&lt;h3 id=&#34;considerations-for-user-agents&#34;&gt;Considerations for user-agents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Many browser developer tools allow viewing a page&amp;rsquo;s media; for example, the Network Inspector allows rendering the body of an individual request. A request for an image inside a &lt;code&gt;spoiler&lt;/code&gt; should not unnecessarily bypass this. Browsers with such features shouldn&amp;rsquo;t ship &lt;code&gt;spoiler&lt;/code&gt; support until a developer-tools toggle for &amp;ldquo;show spoiler contents&amp;rdquo; is ready. Should this also apply to spoiler text?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Users who frequently visit a website may wish for a site-specific setting to auto-show sensitive media. This is a common setting on social media sites.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A simple click-to-toggle would interfere with selection, as repeated clicking is a common way to select text. We should come up with an alternative.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;considerations-for-authors&#34;&gt;Considerations for authors&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In some situations, could alt-text be &lt;em&gt;more&lt;/em&gt; sensitive than visual media? If so, perhaps &lt;code&gt;preview-alt&lt;/code&gt; could apply even without a parent &lt;code&gt;spoiler&lt;/code&gt; element.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Good preview-alt-text is descriptive enough to inform the decision to toggle media, but not so descriptive that it needs a spoiler of its own. Reaching that balance is extremely difficult.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This might be a situation in which SEO-style keyword-stuffing might actually have real merit, to accurately trigger users&amp;rsquo; own keyword filters.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Authors may wish to provide a JavaScript polyfill for clients that lack support, and perhaps preface their content or links with a &lt;code&gt;noscript&lt;/code&gt; warning for clients lacking support for both &lt;code&gt;spoiler&lt;/code&gt; and scripting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How should authors describe severity levels? An image containing blood could depict a minor scrape or severe medical gore. We&amp;rsquo;ll need guidelines on how to do this, just as we have guidelines on alt-text.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;privacy-considerations&#34;&gt;Privacy considerations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User keyword filters may present a fingerprinting vector. Anonymity-focused browsers like the Tor Browser probably shouldn&amp;rsquo;t expose this functionality. Perhaps spoilers combined with lazy-loading should be disqualified from auto-revealing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A user who consistently declines to reveal spoilers with certain keywords in the placeholder text may be fingerprinted accordingly. The Tor Browser&amp;rsquo;s &amp;ldquo;safest&amp;rdquo; mode disables lazy loading and JavaScript, which should close this fingerprinting vector.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;further-work&#34;&gt;Further work&lt;/h3&gt;
&lt;p&gt;We may need to create additional corresponding &lt;abbr title=&#34;Accessible Rich Internet Applications&#34;&gt;ARIA&lt;/abbr&gt; roles for spoilers. I can&amp;rsquo;t decide on an ideal existing one.&lt;/p&gt;
&lt;p&gt;We may also need to define a vocabulary for well-known spoilers, and encourage authors to use that vocabulary when relevant. This could improve how well auto-revealing spoilers works. Of course, I&amp;rsquo;m not proposing that any content matching that vocabulary should receive a spoiler; I&amp;rsquo;m only proposing to choose that vocabulary when writing spoiler-text, if it&amp;rsquo;s relevant. I don&amp;rsquo;t think we should be prescriptive about what to use spoilers on across the entire Web.&lt;/p&gt;
&lt;p&gt;There should be a way to spoiler a whole page, or a whole website, if the primary focus of the page/website is a sensitive topic. This is common on sites devoted to erotic or age-gated content.&lt;/p&gt;
&lt;p&gt;Other areas may benefit from standardized spoiler-like semantics. Someday, chapter indicators in media containers could come with Sponsorblock-inspired vocabulary; some chapters could be marked &amp;ldquo;sensitive&amp;rdquo; and auto-pause while displaying a reason. If other spoiler-like semantics exist, we should create mappings between proposed HTML semantics and existing semantics. Perhaps such an exercise would change how we develop HTML semantics for spoilers.&lt;/p&gt;
&lt;/section&gt;
&lt;section&gt;
&lt;h2 id=&#34;snarky-thoughts-conflicts-of-interests&#34;&gt;Snarky thoughts: conflicts of interests&lt;/h2&gt;
&lt;p&gt;Ad companies probably won&amp;rsquo;t want to hide ads containing sexual/erotic, anxiety-inducing, or shock content behind spoilers; they profit &lt;em&gt;from&lt;/em&gt; what spoilers protect against. Sites with such ads probably won&amp;rsquo;t benefit from hiding such content behind spoilers if ads are exempt.&lt;/p&gt;
&lt;p&gt;A good solution would be for ads to identify themselves as such along with the psychological weaknesses they prey on (porn addictions, anxiety, eating disorders, gambling addictions, etc.) so that user-agents could selectively or globally block them. For some reason, I don&amp;rsquo;t think adtech companies would like this very much. More research is required to find a form of basic compassion that allows dominant advertising business models to exist.&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&#34;doc-acknowledgments&#34;&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://alm.website/me&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Athena Martin&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for providing feedback on an initial draft. She raised concerns about user-agents without support, the possibility of specifying machine-readable severity levels, and printouts.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://keithhacks.cyou/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;~keith&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for bringing up good points concerning prescriptivity of spoiler norms.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://www.1a-insec.net/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Locria Cyber&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for reminding me about BBCode.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;This format is called &lt;code&gt;org.matrix.custom.html&lt;/code&gt;. The &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;Matrix Specification Client-Server API&lt;/cite&gt;, section 11.2.2.6: &lt;a class=&#34;u-url&#34; href=&#34;https://spec.matrix.org/v1.8/client-server-api/#spoiler-messages&#34;&gt;“Spoiler messages”&lt;/a&gt;&lt;/span&gt; specifies the spoiler syntax, semantics, and recommended client behavior.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Note that &lt;code&gt;summary&lt;/code&gt; was originally specified as a block-level button, not an inline element. This may require changes to the definition of &lt;code&gt;summary&lt;/code&gt;. I don&amp;rsquo;t believe that the changes should significantly impact conformant pages, but non-conforming pages that incorrectly use &lt;code&gt;summary&lt;/code&gt; elements without the required &lt;code&gt;details&lt;/code&gt; parent may be impacted. Perhaps we really do need a new element for spoiler summaries.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;I came up with the idea of this attribute when I was browsing some Wikipedia articles on medical topics and ended up on the article for &amp;ldquo;maggot therapy&amp;rdquo;. I had uBlock Origin configured to make large media click-to-load, and the figure captions told me which ones would be safe to load when others were in the room. However, &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/posts/2020/11/23/website-best-practices/#putting-images-in-context&#34;&gt;figure captions aren&amp;rsquo;t a replacement for alt-text&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>De-federating P92</title>
      <link>https://envs.net/~seirdy/posts/2023/06/20/defederating-p92/</link>
      <pubDate>Tue, 20 Jun 2023 22:30:54 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2023/06/20/defederating-p92/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2023/06/20/defederating-p92/">&lt;p&gt;Facebook (&amp;ldquo;Meta&amp;rdquo;) is launching a Twitter alternative that will interoperate with the Fediverse, currently codenamed &amp;ldquo;Barcelona&amp;rdquo; and &amp;ldquo;P92&amp;rdquo; (and &lt;a href=&#34;https://www.theverge.com/2023/6/8/23754304/instagram-meta-twitter-competitor-threads-activitypub&#34;&gt;likely to be known as &amp;ldquo;Threads&amp;rdquo;&lt;/a&gt;). We don&amp;rsquo;t know the extent to which this will or won&amp;rsquo;t interoperate; admins who&amp;rsquo;ve met with Facebook/Meta employees to discuss P92 have signed non-disclosure agreements. Most discussion can be framed in two ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Whether P92 in particular is worth defederating from, should it involve an ActivityPub server.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whether Facebook/Meta projects in principle would be worth proactively blocking, should they attempt to interoperate with a Fediverse instance.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;m going to focus on the latter topic, as we know little about the former.&lt;/p&gt;
&lt;h2 id=&#34;privacy-concerns&#34;&gt;Privacy concerns&lt;/h2&gt;
&lt;p&gt;Of the reasons to resist a Facebook/Meta presence in the Fediverse, privacy is relatively low on the list. The best way to mass-scrape Fediverse content has always been via large, established, well-connected instances&amp;rsquo; federated timelines. It&amp;rsquo;s also quite hard to detect. I imagine that most of this happens through instances such as mastodon.social, fosstodon.org, and mstdn.jp.&lt;/p&gt;
&lt;p&gt;Authorized-fetch is an excellent way to increase friction for harassment, and it ought to be the default. Unfortunately, it does nothing to stop the scraping methods I outlined. Presenting it as a robust privacy measure gives users a false sense of privacy.&lt;/p&gt;
&lt;p&gt;If Facebook/Meta prioritizes data from its users&amp;rsquo; timelines and interactions, then enabling authorized-fetch and de-federating might admittedly offer limited protection. They&amp;rsquo;ve pulled similar moves before, with &lt;a href=&#34;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5544396/&#34;&gt;shadow profiles&lt;/a&gt; of non-Facebook users based on phone numbers of its users&amp;rsquo; contacts.&lt;/p&gt;
&lt;h2 id=&#34;incompatible-values-and-complicity&#34;&gt;Incompatible values and complicity&lt;/h2&gt;
&lt;p&gt;As I&amp;rsquo;ve said elsewhere, Facebook/Meta is doing this for a return on investment. This organization has one of the worst track records in Silicon Valley:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Facebook has aided and abetted in genocide&amp;hellip;more than once. &lt;a href=&#34;https://www.theguardian.com/technology/2021/oct/07/facebooks-role-in-myanmar-and-ethiopia-under-new-scrutiny&#34;&gt;Myanmar and Ethiopia are the main examples&lt;/a&gt; I know of. After Myanmar, Facebook &lt;a href=&#34;https://www.buzzfeednews.com/article/daveyalba/facebook-philippines-dutertes-drug-war&#34;&gt;repeated the same process in the Phillipines, fueling Duterte&amp;rsquo;s bloody drug war&lt;/a&gt; that claimed thousands of lives.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Facebook allowed the rise of Hindu nationalism in India, with &lt;a href=&#34;https://time.com/6112549/facebook-india-islamophobia-love-jihad/&#34;&gt;embarrassingly flimsy responses&lt;/a&gt; after receiving news coverage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Facebook continued on its path &lt;a href=&#34;https://archive.li/ElcvG&#34;&gt;despite knowing the harm caused by its recommendation algorithms&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Facebook played a key role in the &lt;a href=&#34;https://en.wikipedia.org/wiki/Facebook%E2%80%93Cambridge_Analytica_data_scandal&#34;&gt;Facebook–Cambridge Analytica data scandal&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Facebook&amp;rsquo;s &amp;ldquo;real-name policy&amp;rdquo; has &lt;a href=&#34;https://en.wikipedia.org/wiki/Facebook_real-name_policy_controversy&#34;&gt;its own Wikipedia page for its controversies&lt;/a&gt;, most of which relate to cultural supremacy, transphobia, and privacy. &lt;a href=&#34;https://www.teenvogue.com/story/facebook-authentic-name-policy&#34;&gt;Issues persisted years after Facebook claimed to make reforms&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could go on.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Any instance with staff doing any of the above would likely be widely de-federated; Facebook &lt;em&gt;profits&lt;/em&gt; from it. If Breitbart, the Daily Stormer, or Alex Jones announced they were joining the Fediverse, we wouldn&amp;rsquo;t wait until after the obvious happens since &lt;em&gt;we already know what they deem acceptable.&lt;/em&gt; Facebook should not get special treatment.&lt;/p&gt;
&lt;p&gt;I feel an obligation to resist any further growth of this company. Knowing what this organization has done, and without good reason to believe it has &amp;ldquo;stopped&amp;rdquo;, I don&amp;rsquo;t feel comfortable supporting it. Facebook starts projects like this to secure a return on investment. &lt;strong&gt;I don&amp;rsquo;t want to help Facebook secure a return on this investment.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Administrative decisions should be affirmations of shared community values. Facebook has demonstrated that it values growth at the expense of lives, if necessary. At a certain point, the right way to show our values is to put our foot down and say &amp;ldquo;no&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I support initiatives such as &lt;a href=&#34;https://fedipact.online/&#34;&gt;FediPact&lt;/a&gt; to resist interoperating with Facebook/Meta projects. That being said, as I described in &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/posts/2023/05/02/fediverse-blocklists/&#34;&gt;my article outlining my blocklists&lt;/a&gt;, I avoid suspending purely based on federation decisions. Remember that the FediPact list is not an authorative or comprehensive list of instances that will be proactively defederating from Facebook-affiliated servers.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://strangeobject.space/@james/110573260816922578&#34;&gt;See this Fediverse thread&lt;/a&gt; for a longer list, and &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/posts/2021/02/23/keeping-platforms-open/#how-open-platforms-become-closed&#34;&gt;my coverage of how they fragmented the XMPP ecosystem&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>My Fediverse blocklists</title>
      <link>https://envs.net/~seirdy/posts/2023/05/02/fediverse-blocklists/</link>
      <pubDate>Tue, 02 May 2023 07:00:54 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2023/05/02/fediverse-blocklists/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2023/05/02/fediverse-blocklists/">&lt;p&gt;I moderate the &amp;ldquo;pleroma.envs.net&amp;rdquo; Akkoma instance on the Fediverse, as &lt;a href=&#34;https://pleroma.envs.net/users/Seirdy&#34; rel=&#34;me&#34;&gt;@Seirdy@pleroma.envs.net&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I maintain four main blocklists for the Fediverse. Do not import them until you&amp;rsquo;ve read everything until the &amp;ldquo;receipts&amp;rdquo; section. I encourage blocklist skeptics to read the &amp;ldquo;receipts&amp;rdquo; sections, and to treat them as lists of reported content rather than importable blocklists.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/pleroma.envs.net.csv&#34;&gt;The &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A large list of instances that I find worth suspending. After the first couple hundred entries (imported and then reviewed), I started collecting receipts. Since early 2023, every entry has documented reasons and receipts. I share these with multiple people in a collaborative document, but I don&amp;rsquo;t share it publicly due to risk of harassment.
&lt;p&gt;Unlike the other two lists on this page, &lt;strong&gt;it wasn&amp;rsquo;t made for general use.&lt;/strong&gt; You&amp;rsquo;re welcome to use it as reference, or as one of many sources for a consensus-based list with a minimum required consensus level.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/tier0.csv&#34;&gt;&lt;code&gt;tier0.csv&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A much smaller semi-curated subset of &lt;code&gt;pleroma.envs.net&lt;/code&gt; suitable for the majority of instances wishing to uphold the Mastodon Covenant&amp;rsquo;s moderation standards, though somewhat heavy-handed. I hope to make it a good &lt;strong&gt;starting point&lt;/strong&gt; for your instance&amp;rsquo;s blocklist, with wiggle room for your own adjustments. I encourage you to add and remove entries as you see fit. Regularly importing &lt;code&gt;tier0.csv&lt;/code&gt; won&amp;rsquo;t account for retractions; &lt;a href=&#34;https://seirdy.one/pb/tier0-retractions.csv&#34;&gt;a sibling blocklist for tier-0 retractions&lt;/a&gt; exists for &lt;a href=&#34;https://github.com/eigenmagic/fediblockhole&#34;&gt;FediBlockHole&lt;/a&gt; users.
&lt;p&gt;Note that &lt;strong&gt;this list is larger than the bare-minimum I recommend.&lt;/strong&gt; the bare-minimum is FediNuke. If you&amp;rsquo;re skeptical of imported blocklists, you should start there. If you run an instance for many others: please do not blindly import this list unless you intend to review its entries.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/FediNuke.txt&#34;&gt;&lt;code&gt;FediNuke.txt&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A curated subset of &lt;code&gt;tier0.csv&lt;/code&gt;, containing what I deem the &amp;ldquo;worse half&amp;rdquo; of it. This contains instances I really do recommend most people block, or at least avoid. I try to make it a suitable candidate for a &amp;ldquo;default blocklist&amp;rdquo;, and use it as reference when I evaluate the quality of other blocklists.
&lt;p&gt;This list is &lt;strong&gt;not comprehensive;&lt;/strong&gt; to keep this list small, I excluded many really bad instances. I take into account not just severity, but also notoriety and likelihood of reaching/harming people on other instances (e.g. spewing toxicity in others&amp;rsquo; mentions, running block-notification bots, etc). Bad instances that mostly keep to themselves are less likely to cause problems for a new admin, and therefore less likely to get included in this minimal list. Finally, I take into account controversy; in order for this blocklist to fulfill its purpose of widely defederating the worst actors, no entry on it should be too controversial outside of the parts of Fedi already likely to reach tier-0. For this to be possible, &lt;strong&gt;entries must require minimal context.&lt;/strong&gt; If a dossier is necessary to understand why it&amp;rsquo;s worth blocking an instance, no matter how bad it is, it&amp;rsquo;s unlikely to reach FediNuke.&lt;/p&gt;
&lt;p&gt;Criteria are not set in stone. Instances well-known for causing significant problems for many other instances, particularly for instances run by and for marginalized groups, may be added.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;All these lists, just like all my content on seirdy.one, are CC-BY-SA licensed. However, I&amp;rsquo;d rather you not use them in another blocklist-related project without contacting me first. I made a lot of decisions about how these blocklists work and learned some tough lessons; I&amp;rsquo;d rather not see someone repeat my mistakes.&lt;/p&gt;
&lt;p&gt;This post is an attempt to document how they are made, their differences, their intended use, and especially their caveats. It also contains a work-in-progress list of receipts for instances in FediNuke and my Tier-0.&lt;/p&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#how-tier-0-and-fedinuke-work&#34;&gt;How Tier-0 and FediNuke work&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#overrides&#34;&gt;Overrides&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#bias-sources&#34;&gt;Bias sources&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#motivation-for-including-personal-bias&#34;&gt;Motivation for including personal bias&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#refreshing&#34;&gt;Refreshing&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#retractions&#34;&gt;Retractions&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#intended-use&#34;&gt;Intended use&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#rationale-for-creating-two-subsets&#34;&gt;Rationale for creating two subsets&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#use-fediblockhole&#34;&gt;Use FediBlockHole&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#trust-but-verify&#34;&gt;Trust, but verify&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#mistakes-made&#34;&gt;Mistakes made&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#early-april-2023-oliphants-max-list-containing-bad-entries&#34;&gt;Early April 2023: Oliphant&amp;rsquo;s max list containing bad entries&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#july-2023-bad-receipt-for-bungleonline&#34;&gt;July 2023: bad receipt for bungle.online&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#other-errata&#34;&gt;Other errata&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#important-modifications-before-importing&#34;&gt;Important modifications before importing&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#supplementary-blocklists&#34;&gt;Supplementary blocklists&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#frequently-asked-questions&#34;&gt;Frequently-asked questions&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#why-dont-you-use-tags-for-easy-filtering&#34;&gt;Why don&amp;rsquo;t you use tags for easy filtering?&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#how-do-i-get-off-a-list&#34;&gt;How do I get off a list?&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#receipts&#34;&gt;Receipts&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#receipt-criteria&#34;&gt;Receipt criteria&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#fedinuke-entries&#34;&gt;FediNuke entries&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#tier-0-entries-excluding-fedinuke&#34;&gt;Tier-0 entries, excluding FediNuke&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#future&#34;&gt;Future&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;h2 id=&#34;how-tier-0-and-fedinuke-work&#34;&gt;How Tier-0 and FediNuke work&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://seirdy.one/pb/tier0.csv&#34;&gt;My tier-0 list&lt;/a&gt; is a subset of the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist. It contains entries that appeared on at least &lt;strong&gt;15 out of 27&lt;/strong&gt; other hand-picked instance blocklists (&amp;ldquo;bias sources&amp;rdquo;), with exceptions detailed below. Not all Tier-0 entries have the same level of severity; a smaller list containing what I personally deem the &amp;ldquo;worse half&amp;rdquo; of Tier 0 is &lt;a href=&#34;https://seirdy.one/pb/FediNuke.txt&#34;&gt;FediNuke.txt&lt;/a&gt;. &lt;strong&gt;Consensus&lt;/strong&gt; builds Tier-0; &lt;strong&gt;severity&lt;/strong&gt; builds FediNuke.&lt;/p&gt;
&lt;p&gt;When I add a bias source, I may also increase the minimum number of votes required if I find that its blocklist is too close to (or mainly just imports all of) tier-0 or the blocklist of a bias source&amp;rsquo;s blocklist. That&amp;rsquo;s the reason why the threshold is 15 instead of 13 or 14.&lt;/p&gt;
&lt;p&gt;All entries use the root domains when applicable, or are as close to the root domain as possible without triggering false-positives.&lt;/p&gt;
&lt;h3 id=&#34;overrides&#34;&gt;Overrides&lt;/h3&gt;
&lt;p&gt;There were some block-overrides for instances with fewer than 15 votes. Here&amp;rsquo;s how I went about overriding:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If an instance has &lt;strong&gt;10 votes,&lt;/strong&gt; I may elect to add it after additional review instead of waiting for it to hit 15 votes.&lt;/li&gt;
&lt;li&gt;If an instance is run by &lt;strong&gt;the same staff as another Tier-0 instance&lt;/strong&gt; and has &lt;strong&gt;at least 5 votes,&lt;/strong&gt; I may add it after asking other admins about it and getting multiple thumbs-up from admins who import tier-0.&lt;/li&gt;
&lt;li&gt;If an instance contains &lt;strong&gt;blatant/unapologetic bigotry&lt;/strong&gt; (something really undeniable, like Nazi imagery or excessive use of slurs in violent/hateful/definitely-not-reclaimed contexts) with staff approval or involvement, I may add it to both tier-0 and &lt;code&gt;FediNuke.txt&lt;/code&gt; after I get multiple thumbs-up.&lt;/li&gt;
&lt;li&gt;If an instance becomes &lt;strong&gt;risky even to many tier-0 instances&lt;/strong&gt; (untagged gore, dox attempts, significant cybersecurity risk, &lt;abbr title=&#34;child sexual abuse material&#34;&gt;CSAM&lt;/abbr&gt;, etc. with staff approval or involvement): I may add it to both right away, skipping any process. This is rare.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Under ten controversial entries were excluded despite having more than enough votes, after consulting with other admins. Typically, these were instances that didn&amp;rsquo;t pose a major safety risk, but did fail many admins&amp;rsquo; &amp;ldquo;vibe check&amp;rdquo; or exhibit major governance issues.&lt;/p&gt;
&lt;p&gt;I also excluded Twitter mirrors such as BirdSiteLive and bird.makeup, and bridges to other social media platforms; &lt;a href=&#34;#supplementary-blocklists&#34;&gt;I maintain supplementary lists for those&lt;/a&gt; that don&amp;rsquo;t require consensus.&lt;/p&gt;
&lt;h3 id=&#34;bias-sources&#34;&gt;Bias sources&lt;/h3&gt;
&lt;p&gt;Criteria for a bias source:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Has a blocklist I can easily download, possibly with an API key.&lt;/li&gt;
&lt;li&gt;Practices timely and proactive moderation: doesn&amp;rsquo;t just wait for another instance start interacting and cause trouble, and updates more often than once a month. Evaluating this takes time.&lt;/li&gt;
&lt;li&gt;Blocks at least half of &lt;code&gt;FediNuke.txt&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The final &lt;code&gt;tier0.csv&lt;/code&gt; isn&amp;rsquo;t a pure representation of agreement between instances; it contains overrides and is merely a subset of the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist. Other lists only serve to determine the bias used for filtering the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist. The &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist is technically the only &amp;ldquo;real source&amp;rdquo;. Other bias sources shouldn&amp;rsquo;t be held responsible for the final &lt;code&gt;tier0.csv&lt;/code&gt; contents. I&amp;rsquo;ll explain my motivation for doing this in the next section.&lt;/p&gt;
&lt;p&gt;Since accountability for &lt;code&gt;tier0.csv&lt;/code&gt; rests on me rather than on other instances, I don&amp;rsquo;t publish the current bias sources. Blame for any problems in &lt;code&gt;tier0.csv&lt;/code&gt; should rest with me, not them.&lt;/p&gt;
&lt;h3 id=&#34;motivation-for-including-personal-bias&#34;&gt;Motivation for including personal bias&lt;/h3&gt;
&lt;p&gt;If &lt;code&gt;tier0.csv&lt;/code&gt; were merely an unbiased list of the most widely blocked instances, then being on the list would become a self-fulfilling point of no return. If an instance gets blocked by enough other instances, then it shows up on my lists. If an instance shows up on my lists, it will get blocked by other instances which import my lists. If more instances block it&amp;hellip;you get the picture. This leaves little room for retractions and mistakes. By making all my blocklists a subset of the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist, I ensure only one party needs to be convinced to remove an entry.&lt;/p&gt;
&lt;p&gt;Some instances migrate their domains. If the old instance was already deemed worthy of a suspension and the new instance maintains the same staff with no visible attempt to change its reputation, then I deem the new location to be as block-worthy as the old location and make an override. It&amp;rsquo;s the same bad actors under a different banner.&lt;/p&gt;
&lt;h3 id=&#34;refreshing&#34;&gt;Refreshing&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Refreshes are a manual process.&lt;/strong&gt; Refreshes update my tier-0 list, but do not update FediNuke; that list is a manually-curated subset of my tier-0 list. Every time I refresh, I get prompted with changes (if they exist) so I can review them. Since my tier-0 is a subset of the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist, all additions should have some level of approval from me already, but I&amp;rsquo;ve started giving new additions a second look anyway. Manual review, subsetting the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist, having a large number of bias sources, and some level of vetting for my bias sources should mitigate the risk of one bias source &amp;ldquo;going rogue&amp;rdquo; and compromising its blocklist right before a refresh.&lt;/p&gt;
&lt;h3 id=&#34;retractions&#34;&gt;Retractions&lt;/h3&gt;
&lt;p&gt;A separate list exists for retractions from my tier0.csv list. I don&amp;rsquo;t add entries to my retractions list when I remove dead instances, or when an admin on a removed instance prefers not to be included in it (some wish to remain less prominent).&lt;/p&gt;
&lt;h2 id=&#34;intended-use&#34;&gt;Intended use&lt;/h2&gt;
&lt;p&gt;The original goal was to make a blocklist appealing to instances with a more laid-back moderation approach, so that they would actually implement a decent blocklist and limit the reach of the worst actors. Unfortunately, the final &lt;code&gt;tier0.csv&lt;/code&gt; blocklist is 350+ entries; this is still a bit much for the moderate instances.&lt;/p&gt;
&lt;p&gt;I pared that down to &lt;code&gt;FediNuke.txt&lt;/code&gt;, which contains instances that were both really bad &lt;em&gt;and&lt;/em&gt; well-known. It&amp;rsquo;s kind of hard to overlook how shitty each instance on the &lt;code&gt;FediNuke.txt&lt;/code&gt; subset is. Common themes tend to be repeated unwelcome sui-bait&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; from instance staff against individuals, creating or spreading dox materials against other users,&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; unapologetic bigotry, uncensored shock content, and a complete lack of moderation.&lt;/p&gt;
&lt;p&gt;I think if you&amp;rsquo;re starting a well-moderated instance, Tier 0 is a decent place to start (that&amp;rsquo;s why it&amp;rsquo;s in the standard CSV format). You should add and remove entries as you see fit. If you&amp;rsquo;re making a client and want to give it a built-in blocklist, or are looking for a good &amp;ldquo;default&amp;rdquo; blocklist: FediNuke is a good option.&lt;/p&gt;
&lt;p&gt;However: if your instance grows larger (or if you intend to grow): you should be intentional about your moderation decisions, present and past. Your members ostensibly trust you, but not me. See &lt;a href=&#34;#trust-but-verify&#34;&gt;the &amp;ldquo;trust but verify&amp;rdquo; section&lt;/a&gt; for for more information.&lt;/p&gt;
&lt;h3 id=&#34;rationale-for-creating-two-subsets&#34;&gt;Rationale for creating two subsets&lt;/h3&gt;
&lt;p&gt;I used to just make a Tier-0 list. Later, I added the FediNuke list. Some people have asked why I don&amp;rsquo;t just use one or the other; if Tier-0 was big enough to warrant FediNuke, why publish Tier-0 at all?&lt;/p&gt;
&lt;p&gt;I have two reasons for maintaining two blocklists:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I didn&amp;rsquo;t feel comfortable placing some Tier-0 instances right next to, e.g., openly Nazi instances when they weren&amp;rsquo;t at the same level of severity. FediNuke&amp;rsquo;s existence establishes that some instances on the list are much worse than others. Maintaining multiple blocklists makes their subjectivity more obvious.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The lists can work together. As I previously mentioned, the division makes it easier for people to feel comfortable importing blocks. Some admins have found that importing FediNuke and gradually combing through the rest of Tier-0 is more approachable than an &amp;ldquo;all or nothing&amp;rdquo; approach.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;use-fediblockhole&#34;&gt;Use FediBlockHole&lt;/h3&gt;
&lt;p&gt;The CSV format I use is the format used by &lt;a href=&#34;https://github.com/eigenmagic/fediblockhole&#34;&gt;FediBlockHole&lt;/a&gt;. I do this for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;FediBlockHole supports retractions: admins can configure a merge strategy to support downgrading an entry&amp;rsquo;s severity, with the lowest severity (&lt;code&gt;noop&lt;/code&gt;) being equivalent to a removal with an optional reason.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Other blocklists use my blocklists as sources, and are powered by FediBlockHole.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If FediBlockHole supports your Fediverse server (it currently only supports the Mastodon admin APIs), I recommend using that if you want retractions to work.&lt;/p&gt;
&lt;h3 id=&#34;trust-but-verify&#34;&gt;Trust, but verify&lt;/h3&gt;
&lt;p&gt;I totally get resistance to blindly importing blocklists; I don&amp;rsquo;t actually feel comfortable going the &amp;ldquo;import and forget&amp;rdquo; route myself! The first couple hundred entries of the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist started with a few imports, but all domains have since been manually reviewed. For admins who don&amp;rsquo;t feel comfortable &amp;ldquo;outsourcing&amp;rdquo; their moderation to blocklist authors: I generally see pre-made blocklists as a &lt;em&gt;starting point.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Importing &lt;code&gt;FediNuke.txt&lt;/code&gt; and then individually importing &lt;code&gt;tier0.csv&lt;/code&gt; entries after manual review is a decent way to balance two conflicting needs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The need to verify suspensions.&lt;/li&gt;
&lt;li&gt;Not having the time/spoons to verify all the entries.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another option is to use some text-processing tools to find entries that are common between Tier-0 and another trusted instance&amp;rsquo;s blocklist. You can import the overlap.&lt;/p&gt;
&lt;p&gt;Finally, you could just do something else entirely. I never use &amp;ldquo;your blocklist is different from mine&amp;rdquo; as a block-reason; even &amp;ldquo;totally open federation&amp;rdquo; is never the sole reason for &lt;code&gt;pleroma.envs.net&lt;/code&gt; suspending an instance. Suspending instances for not using my own blocklist feels wrong; it&amp;rsquo;d turn these lists into a source of authority and cross the line from moderation to cop behavior.&lt;/p&gt;
&lt;p&gt;Before you decide to trust one of my lists, please read the &amp;ldquo;Mistakes made&amp;rdquo; section.&lt;/p&gt;
&lt;h2 id=&#34;mistakes-made&#34;&gt;Mistakes made&lt;/h2&gt;
&lt;p&gt;Here, I publicly document all significant mistakes I&amp;rsquo;ve made in the process. I sort entries in descending order by date addressed.&lt;/p&gt;
&lt;p&gt;One mistake hasn&amp;rsquo;t yet been listed; I&amp;rsquo;ll wait for approval from one of the people impacted.&lt;/p&gt;
&lt;h3 id=&#34;early-april-2023-oliphants-max-list-containing-bad-entries&#34;&gt;Early April 2023: Oliphant&amp;rsquo;s max list containing bad entries&lt;/h3&gt;
&lt;p&gt;I made a mistake that didn&amp;rsquo;t have a negative impact on my lists, but did impact someone else&amp;rsquo;s. Even if my own lists came out okay, the fact that I allowed this to happen should be enough reason for you to seriously question my judgement.&lt;/p&gt;
&lt;p&gt;I used to work with &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://oliphant.social/@Oliphant&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Oliphant&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; when generating lists.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; Oliphant offered &lt;a href=&#34;https://codeberg.org/oliphant/blocklists&#34;&gt;his own respository of blocklists&lt;/a&gt; (&lt;a href=&#34;https://github.com/sgrigson/oliphant&#34;&gt;GitHub mirror&lt;/a&gt;). Using an approach inspired by my &lt;code&gt;tier0.csv&lt;/code&gt; generation process, he made lists generated from consensus across other lists. Unlike &lt;code&gt;tier0.csv&lt;/code&gt;, the generated lists don&amp;rsquo;t have significant manual curation. Oliphant&amp;rsquo;s tier-1, tier-2, and tier-3 blocklists required decreasing levels of consensus. Until recently, he also offered a &amp;ldquo;unified max&amp;rdquo; blocklist containing &lt;del&gt;any entry common across at least two other blocklists&lt;/del&gt; &lt;ins datetime=&#34;2023-05-02T08:38:00-07:00&#34;&gt;every entry from any trusted source&lt;/ins&gt;.&lt;/p&gt;
&lt;p&gt;One of Oliphant&amp;rsquo;s sources was a single-user instance with many blocks made for personal reasons: the admin was uncomfortable with topics related to sex and romance. Blocking for personal reasons on a personal instance is totally fine, but those blocks shouldn&amp;rsquo;t make their way onto a list intended for others to use. The admin of this instance gave permission to use this blocklist. However, &lt;strong&gt;they did warn us of this fact.&lt;/strong&gt; With my own encouragement, &lt;strong&gt;we decided to use their list anyway.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I had reason to be comfortable with the personal nature of this blocklist. This was was &lt;strong&gt;one out of 20&lt;/strong&gt; bias sources used for &lt;code&gt;tier0.csv&lt;/code&gt; generation, and &lt;code&gt;tier0.csv&lt;/code&gt; is merely a subset of the &lt;code&gt;pleroma.envs.net&lt;/code&gt; blocklist. These two facts prevented someone else&amp;rsquo;s one-off &amp;ldquo;personal&amp;rdquo; blocks from making its way onto my list. I also found that adding this trusted source only introduced a dozen generally uncontroversial entries to &lt;code&gt;tier0.csv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, the situation was different for Oliphant&amp;rsquo;s unified-max blocklist. Several entries made that list for personal reasons. I focused too much on my &lt;code&gt;tier0.csv&lt;/code&gt; and failed to notice that anything was off with Oliphant&amp;rsquo;s lists, even though I bore much responsibility for this blunder.&lt;/p&gt;
&lt;p&gt;&lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://arf.gay/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Tyr&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; from pettingzoo.co raised important issues in a now-deleted thread after noticing his instance&amp;rsquo;s inclusion in the unified-max blocklist. He pointed out that offering a unified-max list containing these blocks is a form of homomisia: it risks hurting sex-positive queer spaces. Simply claiming that the unified-max list isn&amp;rsquo;t intended to be imported isn&amp;rsquo;t enough; there&amp;rsquo;s a real risk that future admins may import it without reading the documentation. I recommend giving the thread a read.&lt;/p&gt;
&lt;p&gt;Oliphant got understandable push-back for this issue in his blocklists, but it&amp;rsquo;s not fair for all of the criticism to be directed at him and none at me. Many small mistakes from multiple people, including me, cascaded into one big failure.&lt;/p&gt;
&lt;p&gt;Since then, Oliphant has removed that admin&amp;rsquo;s list (and his own) from his blocklists&amp;rsquo; trusted sources. I removed the same ones. Oliphant also stopped generating the unified-max blocklist, as the potential for misuse was too great. I became less involved in Oliphant&amp;rsquo;s list; by the end of August 2023, I decided to withdraw from the project completely. I&amp;rsquo;m not prohibiting the use of my blocklists in raw-domain form, as I don&amp;rsquo;t think a &amp;ldquo;list of domains&amp;rdquo; constitutes a creative work worth restricting beyond the provisions of a CC-BY-SA license.&lt;/p&gt;
&lt;h3 id=&#34;july-2023-bad-receipt-for-bungleonline&#34;&gt;July 2023: bad receipt for bungle.online&lt;/h3&gt;
&lt;p&gt;A receipt for bungle.online, at the time a tier-0 instance, cited slurs from the admin account. One was a racial slur. However, I later found that the slur may have been used in a reclaimed context. I subsequently demoted the instance to tier-1 and removed that receipt. I later abandoned the tier-1 blocklist entirely.&lt;/p&gt;
&lt;p&gt;Now I endeavor to be more careful about examining my preconceived notions when using slur-usage as a receipt. If a receipt revolves around slur usage, I should do a better job considering &lt;em&gt;how&lt;/em&gt; the slur was used if there aren&amp;rsquo;t many other receipts indicating a pattern of discriminatory usage. I also should specifically seek approval from people of the relevant marginalized identity before publishing.&lt;/p&gt;
&lt;h3 id=&#34;other-errata&#34;&gt;Other errata&lt;/h3&gt;
&lt;p&gt;More minor corrections:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;August 2023: I mistakenly said that ryona.agency and plagu.ee have an MRF policy to convert DMs to public posts. This was false: the policy converts followers-only and unlisted posts to public, but not DMs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;August 2023: I assumed that an account called &amp;ldquo;Shishihime&amp;rdquo; was a bot. The admin later claimed that it was an actual user. I then retracted the &amp;ldquo;bot&amp;rdquo; description.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;September 2023: I incorrectly stated that a local user on ap.maladaptive.art was a staff member. I retracted the statement.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;important-modifications-before-importing&#34;&gt;Important modifications before importing&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;If you have read this far&lt;/strong&gt; and plan to import my lists or a list that imports mine, please delete the following fake entries from the lists or modify the &amp;ldquo;canary&amp;rdquo; subdomains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;000delete.this.line.if.you.have.read.the.documentation.on.seirdy.one
canary.tier1.example.com
canary.tier0.example.com
canary.fedinuke.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Doing so signals that you&amp;rsquo;ve read these docs. If you build a consensus-based blocklist that uses my lists as a source, I suggest adding your own canary domains. &amp;ldquo;tier1&amp;rdquo; is a legacy indicator for a blocklist I retired.&lt;/p&gt;
&lt;p&gt;If you see an instance whose blocklist contains these entries, unmodified: if it&amp;rsquo;s a large or open-registration instance, assume the moderators aren&amp;rsquo;t doing their jobs and &lt;em&gt;do not register&lt;/em&gt; for it. Single-user or tiny tight-knit instances are free to import whatever they want, though. Moderators of large or open-registration instances should be willing to set aside ten minutes to read something before importing a list.&lt;/p&gt;
&lt;p&gt;If you run a non-private instance that subscribes to a blocklist (whether mine or someone else&amp;rsquo;s) with minimal manual review, I strongly recommend saying so in your instance&amp;rsquo;s &amp;ldquo;About&amp;rdquo; page or equivalent. Users should know who is responsible for moderation, and that the biases of their instance staff don&amp;rsquo;t paint the full picture of the biases of the instance&amp;rsquo;s moderation.&lt;/p&gt;
&lt;h2 id=&#34;supplementary-blocklists&#34;&gt;Supplementary blocklists&lt;/h2&gt;
&lt;p&gt;Some supplementary blocklists I maintain with very different criteria:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/bsl.txt&#34;&gt;BirdSiteLive and bird.makeup&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;These are services that allow Fediverse users to follow any Twitter user. Now that far-right figures are back on Twitter, these instance pose a problem. Admins wishing to ban a single Twitter user will need to ban that user across over 100 different Twitter mirrors. Moreover, any interactions with bridged accounts are unseen by the account holder on Twitter. Twitter users may not have consented to such mirroring. Admins wishing to simply ban mass-Twitter-mirroring can import this list.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/bridges.txt&#34;&gt;Bridges&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Bridges to other social media platforms, &lt;em&gt;excluding&lt;/em&gt; Twitter/X bridges, that aren&amp;rsquo;t opt-in. Bridges to Nostr are common. These are excluded from tier0.csv as they&amp;rsquo;re in a dedicated list. Nostr is especially worth blocking because most bridges don&amp;rsquo;t appear to do significant moderation or delegate to relays that do, effectively requiring moderators to moderate the whole network in its unmoderated form and potentially duplicate their work across multiple Nostr bridges.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/corpo.txt&#34;&gt;Corporate social media with user-hostile dark patterns&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A short list containing instances run by social media companies that have displayed user-hostile behavior, for anybody who doesn&amp;rsquo;t wish to support such practices. Privacy abuse, growth-mindsets, dark patterns, and a history of vendor lock-in are common (but not all universal) themes. Not updated very often. I&amp;rsquo;ve explained my views on Threads in another post: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;../../../../2023/06/20/defederating-p92/&#34;&gt;De-federating P92&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://seirdy.one/pb/spammy-subdomains.txt&#34;&gt;Spammy subdomains&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;These domains are often used for HTTP tunneling or short-lived spin-up-spin-down servers. Fediverse instances running on their subdomains almost certainly aren&amp;rsquo;t in it for the long haul, and very frequently shut down within hours or days without doing a clean self-destruct. Note that this is not to be confused with traditional dynamic-DNS subdomains, which are often used for longer-lived servers (although some admins do understandably block those anyway).&lt;/dd&gt;
&lt;dd&gt;This list might prove useful in non-Fediverse contexts as well; I imagine it could be useful for moderating Matrix rooms.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;frequently-asked-questions&#34;&gt;Frequently-asked questions&lt;/h2&gt;
&lt;h3 id=&#34;why-dont-you-use-tags-for-easy-filtering&#34;&gt;Why don&amp;rsquo;t you use tags for easy filtering?&lt;/h3&gt;
&lt;p&gt;Tags remove nuance. There exist gray areas that make it hard to determine whether an instance clearly fits within a tag; choosing to include or exclude that instance is choosing to make a statement about what &amp;ldquo;counts&amp;rdquo;. I prefer to describe an instance&amp;rsquo;s reason in my own words, properly.&lt;/p&gt;
&lt;h3 id=&#34;how-do-i-get-off-a-list&#34;&gt;How do I get off a list?&lt;/h3&gt;
&lt;p&gt;If you believe a receipt is inaccurate or you don&amp;rsquo;t belong on a given list, contact me. My contact info should be easy to find on my &amp;ldquo;about&amp;rdquo; page. I can&amp;rsquo;t promise I&amp;rsquo;ll respond quickly; feel free to re-send your request if I don&amp;rsquo;t respond within a couple days. I might not be receptive to requests from FediNuke instances, though. I&amp;rsquo;d prefer if you made an effort to respond to the concerns raised by a receipt if possible.&lt;/p&gt;
&lt;h2 id=&#34;receipts&#34;&gt;Receipts&lt;/h2&gt;
&lt;p&gt;The following are receipts for instances on my blocklists. Read the text surrounding a link before navigating to it, and let that context serve as a content-warning. No links point directly to the blocked instance; all go to a third-party archiving service.&lt;/p&gt;
&lt;p&gt;I use archive links instead of screenshots. Screenshots pose accessibility issues, can be doctored, and are easy to take out of context.&lt;/p&gt;
&lt;h3 id=&#34;receipt-criteria&#34;&gt;Receipt criteria&lt;/h3&gt;
&lt;p&gt;Receipts are biased towards patterns in staff behavior or pervasive patterns among users with staff approval, as that generally won&amp;rsquo;t be solved with a federated report. A one-off user action taken out of context, without any sign of staff endorsement, isn&amp;rsquo;t enough to end up on one of these lists because it&amp;rsquo;s not indicative of an instance&amp;rsquo;s moderation policies.&lt;/p&gt;
&lt;p&gt;Receipts revolving around slur usage depend on context. Slurs used in reclaimed contexts aren&amp;rsquo;t grounds for defederation. Patterns of slur usage in discriminatory contexts would warrant adding a receipt. I&amp;rsquo;m a native English speaker, so I mainly consider English slurs. I give the benefit of doubt to users who aren&amp;rsquo;t native English speakers when using English slurs, depending on context. When I&amp;rsquo;m unsure, I ask for feedback from other mods from the relevant marginalized group.&lt;/p&gt;
&lt;p&gt;Some receipts aren&amp;rsquo;t reasons to block, but exist to contextualize other receipts. For example: I may mention that an instance has open-registration only to highlight that the instance&amp;rsquo;s moderation policies will allow additional bad actors in the future.&lt;/p&gt;
&lt;p&gt;One exception is receipts for legally risky media (e.g. sexual depictions of minors): I don&amp;rsquo;t publish archive links for those. It should be easy to verify them yourself if you need to; I&amp;rsquo;ll provide a user handle if necessary.&lt;/p&gt;
&lt;p&gt;I grouped some related domains together and added receipts to them collectively. If you see multiple consecutive domains, that&amp;rsquo;s why.&lt;/p&gt;
&lt;details open=&#34;&#34;&gt;&lt;summary&gt;Toggle receipts&lt;/summary&gt;
&lt;h3 id=&#34;fedinuke-entries&#34;&gt;FediNuke entries&lt;/h3&gt;
&lt;p&gt;Criteria for a good FediNuke receipt is stricter than the aforementioned criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reblogs are only significant if they are from a staff member and are boosting local users. They are mentioned alongside other receipts to indicate that the content in question is permitted by staff.&lt;/li&gt;
&lt;li&gt;Each instance must have multiple receipts. I&amp;rsquo;m working towards getting at least three receipts for most instances.&lt;/li&gt;
&lt;li&gt;For larger instances: receipts must show staff behavior, or show consistent behavior from several users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;This section is a work-in-progress,&lt;/strong&gt; and it will grow with time.&lt;/p&gt;
 &lt;dl&gt;
&lt;dt id=&#34;13bells&#34; tabindex=&#34;-1&#34;&gt;13bells.com&lt;/dt&gt;
&lt;dd&gt;Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/dT9Am&#34;&gt;Sandy Hook school shooting conspiracy theories&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/Km8Ju&#34;&gt;transmisia&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810193444/https://13bells.com/@amiko/110810353137172742&#34;&gt;queermisia&lt;/a&gt;. Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/9Kvug&#34;&gt;spreads vaccine misinformation&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;1611&#34; tabindex=&#34;-1&#34;&gt;1611.social&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230628203218/https://1611.social/@tyler/posts/AX9r68rwjhEQzMKJbU&#34;&gt;antisemitism from admin&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.li/qFhQQ&#34;&gt;anti-vax from admin&lt;/a&gt; with other local members, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/3wIRL&#34;&gt;antisemitic caricature from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;4aem&#34; tabindex=&#34;-1&#34;&gt;4aem.com&lt;/dt&gt;
&lt;dd&gt;Freeze peach PeerTube instance on the &amp;ldquo;tube&amp;rdquo; subdomain, hosting blatant antisemitic content. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/80Zwu&#34;&gt;&amp;ldquo;Clown World&amp;rdquo; dogwhistles&lt;/a&gt;, antisemitic &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/06UiV&#34;&gt;&amp;ldquo;Why Kanye West is right&amp;rdquo;&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/itBDB&#34;&gt;more antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;5dollah&#34; tabindex=&#34;-1&#34;&gt;5dollah.click&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803174643/https://5dollah.click/notice/AYFv0JRxfVez3K6ftQ&#34;&gt;Blatantly racist use of slurs&lt;/a&gt; from staff account, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803174620/https://5dollah.click/notice/AYGifHRMwMFURlzgye&#34;&gt;more racism from same account&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;The &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804231543/https://5dollah.click/notice/AXpsKVU45gZ5zHyVTk&#34;&gt;other staff account is racist too&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805071034/https://5dollah.click/notice/AYEAhzfTglQXRCnOhU&#34;&gt;Extreme racism from staff&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804225043/https://5dollah.click/about&#34;&gt;&amp;ldquo;About&amp;rdquo; page&lt;/a&gt; lists no rules.&lt;/dd&gt;
&lt;dt id=&#34;adachi&#34; tabindex=&#34;-1&#34;&gt;adachi.party&lt;/dt&gt;
&lt;dd&gt;The instance in question is on the &amp;ldquo;pleroma&amp;rdquo; subdomain. Its &amp;ldquo;about&amp;rdquo; page has the &amp;ldquo;Kill, behead, roundhouse kick&amp;rdquo; copypasta with racial slurs. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/muPe1&#34;&gt;Archived &amp;ldquo;about&amp;rdquo; page&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Later updated rules to include &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/6Tpq5&#34;&gt;&amp;ldquo;must advocate for racism/fascism/nazism&amp;rdquo;&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730175847/https://pleroma.adachi.party/notice/AYAMup3aR6WhWwuHXU&#34;&gt;Admin posts racist transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230811042822/https://pleroma.adachi.party/notice/AYbC2xyPJdrZH05CWO&#34;&gt;mass-tags other users with blatant racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;adtension&#34; tabindex=&#34;-1&#34;&gt;adtension.com&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/Z3O7P&#34;&gt;posts blatant anti-Black racism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.04-010357/https://mastodon.adtension.com/@admin/111173994405081956&#34;&gt;doubles-down with more&lt;/a&gt; after being called out on it.&lt;/dd&gt;
&lt;dt id=&#34;annihilation&#34; tabindex=&#34;-1&#34;&gt;annihilation.social OR dembased.xyz&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://pleroma.envs.net/notice/ASzpsfBstyxOmEtvEG&#34;&gt;#FediBlock on 2023-02-24&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;Hosts a block-notification bot, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/BAid6&#34;&gt;with the handle &amp;ldquo;blockbot&amp;rdquo;&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/VFO2x&#34;&gt;a defederation-notification bot&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230729234055/https://annihilation.social/notice/ASwz1H2DlWPaIkUWki&#34;&gt;Racism from admin&lt;/a&gt;. In light of this, I&amp;rsquo;m not inclined to give the benefit of doubt over the cross in his display name and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230920191234/https://social.xenofem.me/notice/AZwvB187WVZNkbgCDg&#34;&gt;doubling down on vaguely antisemitic posts&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231103144028/https://annihilation.social/notice/AbMGtcC0mKuqdyKQxE&#34;&gt;Another example of antisemitic caricatures from the admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240320005033/https://annihilation.social/notice/Af5EadUiy1vaqFtQxM&#34;&gt;Blatant antisemitism from local user&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;dembased.xyz used to run the predecessor of annihilation.social. A few times since, a small experimental instance has been set up on a subdomain. Both are owned by the same person.&lt;/dd&gt;
&lt;dt id=&#34;anon-kenkai&#34; tabindex=&#34;-1&#34;&gt;anon-kenkai.net&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230729235305/https://peertube.anon-kenkai.com/&#34;&gt;Blatant antisemitic caricature on the landing page&lt;/a&gt; of its &amp;ldquo;peertube&amp;rdquo; subdomain. Admin on the &amp;ldquo;mitra&amp;rdquo; subdomain posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/9p5nw&#34;&gt;anti-pride messages&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;asbestos&#34; tabindex=&#34;-1&#34;&gt;asbestos.cafe&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/d7cfQ&#34;&gt;Racism and ableism from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/LUA10&#34;&gt;Admin sharing a dox attempt&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803032450/https://shrine.moe/notice/AYJfESHlqB0IvHPfqS&#34;&gt;Antisemitism from local user&lt;/a&gt; followed by ableism from admin. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240110032818/https://the.asbestos.cafe/notice/AdgBSAo0q5L63JPXtY&#34;&gt;Admin defends antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803032850/https://pl.starnix.network/notice/AY1JMsQpMH4NukiNE0&#34;&gt;Queermisic user&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20241120043300/https://the.asbestos.cafe/notice/Ao28rL7evIm11h64Dg&#34;&gt;Very explicit anti-blackness from local users&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;baest&#34; tabindex=&#34;-1&#34;&gt;bae.st OR skippers-bin.com&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730000208/https://bae.st/sjw&#34;&gt;Admin profile page has an &amp;ldquo;n-word pass&amp;rdquo;&lt;/a&gt;. Runs a host of bots posting lewd artwork, some of which venture into lolicon and Black-fetishism territory (e.g. &amp;ldquo;NessaBot&amp;rdquo;). Runs &amp;ldquo;glow_in_the_dark_cia_agent&amp;rdquo;, one of the biggest followbots on Fedi. Instance rejects deletes.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231117114815/https://bae.st/users/mactonite&#34;&gt;Another admin has a Confederate battle-flag and unreclaimed transmisic slurs in their display name&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.17-114233/https://skippers-bin.com/@sjw&#34;&gt;skippers-bin.com is run by the same person as bae.st&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;banepost&#34; tabindex=&#34;-1&#34;&gt;banepo.st&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/2c9Js&#34;&gt;Runs a block-notification bot&lt;/a&gt;. Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730035807/https://www.banepo.st/notice/AXRzgFfrwY1BRaa9SK&#34;&gt;antisemitism, homomisia, and transmisia in one post&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/JxXRv&#34;&gt;another with more of the same&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730040446/https://www.banepo.st/notice/AXql6rXn1tybo4umiO&#34;&gt;all of that with a side of ableism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;bassam&#34; tabindex=&#34;-1&#34;&gt;bassam.social&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/r1tDT&#34;&gt;The admin equates people being against anti-queer discrimination with &amp;ldquo;oppression&amp;rdquo;&lt;/a&gt;. After a user &lt;a rel=&#34;nofollow&#34; href=&#34;https://mstdn.social/users/MagicLike/statuses/110430832688299722&#34;&gt;made a FediBlock post against bassam.social&lt;/a&gt;, its instance admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/PQ7j0&#34;&gt;doubled down on permitting bigotry&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;beefyboys&#34; tabindex=&#34;-1&#34;&gt;beefyboys.win&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730042513/https://beefyboys.win/@maldalerts&#34;&gt;Runs a block-notification bot&lt;/a&gt;. Staff member &amp;ldquo;Prude&amp;rdquo; has a profile with &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730043518/https://beefyboys.win/notice/AJfdGhgoE5K3CUV53A&#34;&gt;a racist rant pinned&lt;/a&gt;. Staff member &amp;ldquo;Tyler&amp;rdquo; posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/6qDCI&#34;&gt;&amp;ldquo;racism is cool and natural&amp;rdquo;&lt;/a&gt; followed immediately by racial slurs, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/jGvHn&#34;&gt;other slurs in a non-reclaimed context&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;boymoder&#34; tabindex=&#34;-1&#34;&gt;boymoder.biz&lt;/dt&gt;
&lt;dd&gt;Admin accounts post &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730193948/https://boymoder.biz/notice/AWG1sVpdFr5edzwwUq&#34;&gt;anti-Indian racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730194158/https://boymoder.biz/notice/AWEzwl3QDV8xYxBjpQ&#34;&gt;racist copypasta&lt;/a&gt;. Staff includes &amp;ldquo;meso&amp;rdquo; from the.asbestos.cafe. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230619154748/https://boymoder.biz/notice/AWpLw39olFJZ3Y9kIq&#34;&gt;Incompatible moderation standards&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;brainsoap&#34; tabindex=&#34;-1&#34;&gt;brainsoap.net&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/a6bUB&#34;&gt;dismissive over white supremacy&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/qDoKt&#34;&gt;Nazi humor&lt;/a&gt;&lt;/dd&gt;
&lt;dt id=&#34;breastmilk&#34; tabindex=&#34;-1&#34;&gt;breastmilk.club&lt;/dt&gt;
&lt;dd&gt;Admin &amp;ldquo;leyonhjelm&amp;rdquo; posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730195610/https://breastmilk.club/notice/AX6eLMJ8QENou2HhmS&#34;&gt;transmisic sui-bait&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730195759/https://breastmilk.club/notice/AWy4STyPAWSj5e0SYq&#34;&gt;spamming the &amp;ldquo;mutualaid&amp;rdquo; guppe group with blatant queermisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;brighteon&#34; tabindex=&#34;-1&#34;&gt;brighteon.social&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230724044425/https://brighteon.social/about/more&#34;&gt;Brighteon&amp;rsquo;s &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; marks the instance as a far-right cesspit. Instance is connected to &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230729030855/https://www.brighteon.com/&#34;&gt;the Brighteon network&lt;/a&gt;, a far-right network featuring shows such as &amp;ldquo;The Reality Camp&amp;rdquo; with Stacey Campfield.&lt;/dd&gt;
&lt;dt id=&#34;cachapa&#34; tabindex=&#34;-1&#34;&gt;cachapa.xyz OR cachapa.cc&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-185121/https://moar.cachapa.xyz/notes/9huxc4zgtc&#34;&gt;posts blatant racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-185812/https://moar.cachapa.xyz/notes/9bv4ns2itf&#34;&gt;blatantly racist transmisic sui-biat&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231025062617/https://cachapa.xyz/about/&#34;&gt;Root domain&amp;rsquo;s &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; contains transmisic, racist, queermisic, and other slurs in a list of things the owner &amp;ldquo;hates&amp;rdquo;.&lt;/dd&gt;
&lt;dd&gt;Instance permits lolicon, and runs accounts for it such as &amp;ldquo;Shishihime&amp;rdquo; and &amp;ldquo;NahidaBot&amp;rdquo;; this may be a legal risk, depending on your jurisdiction.&lt;/dd&gt;
&lt;dt id=&#34;caekislove&#34; tabindex=&#34;-1&#34;&gt;caekis.love&lt;/dt&gt;
&lt;dd&gt;Posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-000705/https://cawfee.club/notice/An22HKnnXpVEYtEC8W&#34;&gt;extreme anti-black racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-000358/https://poa.st/@caekislove@caekis.love/posts/An2ohPSMVnGDc7DIbw&#34;&gt;more anti-black racism cross-posted from their Twitter/X account&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-001447/https://cawfee.club/notice/AmuW7DLHXITf8EcpeK&#34;&gt;more&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-001414/https://cawfee.club/notice/AmuLHyrwaXVjvwpmAi&#34;&gt;Extreme antisemitism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-002307/https://cawfee.club/notice/Amg4Ps2Zj2gGguixwe&#34;&gt;more antisemitism&lt;/a&gt; to the point of wishing for genocide.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-002519/https://cawfee.club/notice/AmVU1Qaxls2w69cK6S&#34;&gt;Anti-blackness and antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.17-002238/https://cawfee.club/notice/AmkJ7Fp1MI1UtGnyhE&#34;&gt;Participating in a queermisic harassment campaign&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin and primary user originally on the same &amp;ldquo;caekislove&amp;rdquo; handle on gleasonator.com; &lt;a rel=&#34;nofollow&#34; href=&#34;#gleasonator&#34;&gt;see their receipts on the entry for gleasonator.com&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;cannibal&#34; tabindex=&#34;-1&#34;&gt;cannibal.cafe&lt;/dt&gt;
&lt;dd&gt;Shares some staff with lolison.top; see its FediNuke entry. Staff-endorsed instances in the &amp;ldquo;local bubble&amp;rdquo; include nnia.space, freak.university, rapemeat.express, and other instances on FediNuke for similar reasons.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.28-005227/https://paravielfalt.zone/@regenbogenfisch/111120363605697304&#34;&gt;is explicitly pro-contact&lt;/a&gt;.[^3]&lt;/dd&gt;
&lt;dt id=&#34;catgirl-life&#34; tabindex=&#34;-1&#34;&gt;catgirl.life OR peervideo.club&lt;/dt&gt;
&lt;dd&gt;Both are part of &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230828181259/https://waifuhunter.club/services/&#34;&gt;the Waifu Hunter Club&amp;rsquo;s suite of services&lt;/a&gt;, along with gameliberty.club; see its FediNuke entry. catgirl.life has &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.28-181717/https://catgirl.life/@matrix07012&#34;&gt;the same admin as gameliberty.club&lt;/a&gt;, who &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.28-182409/https://catgirl.life/notes/8wpdshluoy&#34;&gt;has used the domain for block-evasion&lt;/a&gt;. Like gameliberty.club, both instances also permit lolicon.&lt;/dd&gt;
&lt;dt id=&#34;cawfee&#34; tabindex=&#34;-1&#34;&gt;cawfee.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730210913/https://cawfee.club/notice/AY5J5qUA898oge9pa4&#34;&gt;Racism from multiple users, including admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730211327/https://cawfee.club/notice/AXjafVFrE4C3c48Mm8&#34;&gt;Anti-Romani and racist posts from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Users &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730211531/https://cawfee.club/notice/AY1UovIIgAoO6DfDX6&#34;&gt;engaging in more racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730211009/https://cawfee.club/notice/AXoyiP9rictCGP2zrs&#34;&gt;Anti-vax from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;childlove&#34; tabindex=&#34;-1&#34;&gt;childlove.space OR childlove.su&lt;/dt&gt;
&lt;dd&gt;Pro-contact MAP instance.[^1] &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.06-195515/https://monk.ey.business/users/AaRGvnOHPOQxxPJK5Y&#34;&gt;Admin profile&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.06-200835/https://monk.ey.business/users/AaSD9Yd8sWKxZgWrg0%23replies&#34;&gt;user profile&lt;/a&gt;, and several other users identify as pro-contact. Appears to contain many users close to Newgon, a bigoted pro-contact conspiratorial group.&lt;/dd&gt;
&lt;dd&gt;This pro-contact instance &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.06-201812/https://childlove.space/about/&#34;&gt;explicitly allows minors&lt;/a&gt; in its ToS.&lt;/dd&gt;
&lt;dt id=&#34;clew&#34; tabindex=&#34;-1&#34;&gt;clew.lol&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730212140/https://clew.lol/@Tony/posts/ATlNGVY9vg0FLp8WlE&#34;&gt;Racist meme from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730212307/https://clew.lol/@Tony/posts/ATlKwuT1NWt0vjGDCq&#34;&gt;Another racist meme&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730212536/https://clew.lol/@hh1488&#34;&gt;Racial slurs in bio of a user with a white-nationalist dog whistle in their handle&lt;/a&gt; who &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730212719/https://clew.lol/@hh1488/posts/ATxalxgkzTwstq0QNc&#34;&gt;posts NJP propaganda&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803154409/https://clew.lol/notice/AYMCIqKmuogqW2zLd2&#34;&gt;Local users participating in a transmisogynistic harassment campaign&lt;/a&gt; with sui-bait.&lt;/dd&gt;
&lt;dt id=&#34;clubcyberia&#34; tabindex=&#34;-1&#34;&gt;clubcyberia.co&lt;/dt&gt;
&lt;dd&gt;Instance &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730220345/https://clubcyberia.co/notice/AY9kBc1YiuBfP9TVgG&#34;&gt;features anti-black emotes&lt;/a&gt;. Users such as &amp;ldquo;Inginsub&amp;rdquo; often &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730221532/https://clubcyberia.co/notice/AXSJ3fIo5mMORrLYPY&#34;&gt;post blatant racism&lt;/a&gt;. Hosts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730222042/https://clubcyberia.co/users/crunklord420&#34;&gt;a KiwiFarms staff member&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Staff member &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.12-014232/https://clubcyberia.co/notice/AYdQ5Rt3vLgaXzqVtY&#34;&gt;publicizes reports against extremely transmisic harassment&lt;/a&gt; in a reply to said harassment (YWNBAW-like copypasta).&lt;/dd&gt;
&lt;dt id=&#34;cottoncandy&#34; tabindex=&#34;-1&#34;&gt;cottoncandy.cafe&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/2023.12.02-032342/https://monk.ey.business/users/AbX87tTlQhM3rfD02y&#34;&gt;pro-contact MAP admin&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.12.02-032427/https://monk.ey.business/users/Abk2pkdrZc2eWowPYG&#34;&gt;pro-contact user&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.12.02-032716/https://cottoncandy.cafe/about&#34;&gt;Instance local bubble&lt;/a&gt; shows that the admin endorses other pro-contact instances.&lt;/dd&gt;
&lt;dt id=&#34;crlf&#34; tabindex=&#34;-1&#34;&gt;crlf.ninja&lt;/dt&gt;
&lt;dd&gt;Instance admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731191030/https://thechimp.zone/notice/AYGJJeBPdUXSuC7Fui&#34;&gt;endorses sending toxic racist slurs and being &amp;ldquo;horrible&amp;rdquo;&lt;/a&gt; to people for blocking instances.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730231641/https://ryona.agency/notice/AY8AHumTq4cb2lik76&#34;&gt;participated in a transmisic dogpiling campaign&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/hASVN&#34;&gt;Admin publicizes blocks&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.04.10-201320/https://crlf.ninja/notice/AgWVbdmSKxK4JegxU0&#34;&gt;Admin uses triple-paren antisemitic dogwhistle&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;crucible&#34; tabindex=&#34;-1&#34;&gt;crucible.world&lt;/dt&gt;
&lt;dd&gt;Admin participating in &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730231641/https://ryona.agency/notice/AY8AHumTq4cb2lik76&#34;&gt;extremely transmisic harassment&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730232208/https://crucible.world/notice/AYES99sUhEtMulC7M0&#34;&gt;More transmisia from admin&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/WVFrK&#34;&gt;Even more transmisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;cumcamp&#34; tabindex=&#34;-1&#34;&gt;cum.camp OR cum.salon&lt;/dt&gt;
&lt;dd&gt;Instance has MRF policies to reject deletes and run a block-notification bot &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730232539/https://cum.camp/about&#34;&gt;on cum.camp&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20221228172530/https://cum.salon/about&#34;&gt;on cum.salon&lt;/a&gt;. Staff members &amp;ldquo;pernia&amp;rdquo; and &amp;ldquo;nimt&amp;rdquo; are known for &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730234254/https://boymoder.biz/notice/AXyuRlHglkmt1AHPn6&#34;&gt;overly-creepy posts related to sexual assault, esp. CSA&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/gDzD1&#34;&gt;another&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;The cum.salon domain name was recently terminated by PorkBun after several people reported it for publishing dox materials. Other instances have locally overridden their DNS to continue federating until its TLS certificate expires; however, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819012541/https://shitposter.club/notice/AYpWAIw53KQXoohBbM&#34;&gt;it came back after transferring to Epik&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;cunnyborea&#34; tabindex=&#34;-1&#34;&gt;cunnyborea.space&lt;/dt&gt;
&lt;dd&gt;Appears to be a racist pro-contact pedophilia-themed instance. One admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231020044329/https://freespeechextremist.com/users/AabwnOHSvtsRxC0HAm&#34;&gt;has swastikas in their profile bio&lt;/a&gt; and several variations on &amp;ldquo;total ___ death&amp;rdquo;. The other admin&amp;rsquo;s bio &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.20-051331/https://eientei.org/users/$AacBlKKa9AaXillm08&#34;&gt;has blatant racism and antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;decayable&#34; tabindex=&#34;-1&#34;&gt;decayable.ink&lt;/dt&gt;
&lt;dd&gt;Instance is well-known for harassment campaigns.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/KfDpN&#34;&gt;Targeted transmisogynistic harassment&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802213907/https://decayable.ink/notice/AYEnvhUP1mVan0dnCi&#34;&gt;aftermath of said harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/5XvUx&#34;&gt;Racist admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;The &lt;a rel=&#34;nofollow&#34; href=&#34;https://decayable.ink/@Decayable/posts/ATYE6r7bOp2bhCRfdY&#34;&gt;instance introductory post&lt;/a&gt; is chock-full of red flags.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803154310/https://decayable.ink/notice/AYMBCCDwBRL5nQUfGi&#34;&gt;Another instance of haraassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;drc&#34; tabindex=&#34;-1&#34;&gt;detroitriotcity.com&lt;/dt&gt;
&lt;dd&gt;Well-known Nazi instance. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230801230826/https://detroitriotcity.com/about&#34;&gt;Instance &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; says: &lt;q&gt;racial pejoratives, NSFW images &amp;amp; videos, insensitivity and contempt toward differences in sexual orientation and gender identification, and so-called “cyberbullying” are all commonplace on this instance&lt;/q&gt; and has a staff account display name featuring an iron cross. Policies permitting lolicon may make it a legal risk, depending on your jurisdiction.&lt;/dd&gt;
&lt;dt id=&#34;djsumdog&#34; tabindex=&#34;-1&#34;&gt;djsumdog.com&lt;/dt&gt;
&lt;dd&gt;Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231002145800/https://annihilation.social/notice/AZsHN1lZgOVeSltXDU&#34;&gt;blatant transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-144509/https://djsumdog.com/@djsumdog/posts/AZiGbeyuCkMvdtEN5E&#34;&gt;more blatant transmisia&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231002150542/https://pleroma.soykaf.com/notice/AZhV9sPBBYZSEL8LWS&#34;&gt;Defends teaching children to be transmisic on moral grounds&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-144530/https://djsumdog.com/@djsumdog/posts/AZZCfoxpXdfdhH2L3I&#34;&gt;Jan 6th conspiracy theories&lt;/a&gt; while &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-144530/https://djsumdog.com/@djsumdog/posts/AZVZCzBbydqpJfrX4y&#34;&gt;calling participants &amp;ldquo;discount Mandelas&amp;rdquo;&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;drinkanddrive&#34; tabindex=&#34;-1&#34;&gt;drinkanddrive.africa&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20241218020752/https://furville.drinkanddrive.africa/notice/Ap78VH56PvDhQHPyW8&#34;&gt;Extreme anti-Blackness&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20241218021100/https://furville.drinkanddrive.africa/notice/Ap3Tfowqg0h1lBaUs4&#34;&gt;Anti-blackness&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;http://archive.today/2024.12.18-021239/https://furville.drinkanddrive.africa/notice/Ap7gl1MW1cLZkIF7JY&#34;&gt;Violent anti-Blackness&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20241218024743/https://furville.drinkanddrive.africa/notice/Aot6dGB74fnnbevVi4&#34;&gt;Antisemitism&lt;/a&gt;&lt;/dd&gt;
&lt;dt id=&#34;eientei&#34; tabindex=&#34;-1&#34;&gt;eientei.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230801231939/https://eientei.org/about&#34;&gt;Instance &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; explicitly describes it as a racist instance, anad uses racial slurs. MRF policies on the &amp;ldquo;about&amp;rdquo; page feature a block-notification bot and rejecting deletes. Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230801233538/https://eientei.org/notice/AW33QYo0a9vhhJUyC8&#34;&gt;posts antisemitic caricatures&lt;/a&gt;. User &amp;ldquo;lina&amp;rdquo; has &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230801232340/https://eientei.org/users/lina&#34;&gt;a bio with blatant bigotry&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;eveningzoo&#34; tabindex=&#34;-1&#34;&gt;eveningzoo.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/TuRrR&#34;&gt;Transmisia from admin&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802000535/https://eveningzoo.club/@Humpleupagus/posts/AYArUMz4q1OeHMwDxI&#34;&gt;More admin transmisogny&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802000011/https://eveningzoo.club/@Humpleupagus/posts/AYCEaTUm2CXgJZbViq&#34;&gt;Racist meme from admin&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230801235849/https://eveningzoo.club/@Humpleupagus/posts/AYHVUBiXEThuSK3fHM&#34;&gt;Antisemitism from admin&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802000129/https://eveningzoo.club/@Humpleupagus/posts/AYFDemmWklKkoCHOwS&#34;&gt;More antisemitism from admin&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802000313/https://eveningzoo.club/@WeavingTales/posts/AYBsfFdqlsr3nxioz2&#34;&gt;White nationalism from user&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;feministwiki&#34; tabindex=&#34;-1&#34;&gt;feministwiki.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.09.24-141504/https://fedi.feministwiki.org/notice/AmG2K1lGrtC00Wd0kK&#34;&gt;Pedojacketing and misgendering&lt;/a&gt; from admin.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/WaWQK?wr=false&#34;&gt;explicitly promoting transphobia &lt;em&gt;by name&lt;/em&gt; as a moral imperative&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/l8iWb?wr=false&#34;&gt;More misgendering&lt;/a&gt; from admin.&lt;/dd&gt;
&lt;dd&gt;Root domain is full of standard &lt;abbr&gt;TERF&lt;/abbr&gt;/gender-critical talking points.&lt;/dd&gt;
&lt;dt id=&#34;fluf&#34; tabindex=&#34;-1&#34;&gt;fluf.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.02-003048/https://freesoftwareextremist.com/notice/AYHzC307R2T8F9hpI0&#34;&gt;Transmisia from admin&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802003149/https://eientei.org/notice/AYEuW35LVZ48XYOXPk&#34;&gt;more transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802003447/https://shitposter.club/notice/AYEKwm6THNpfFCVjm4&#34;&gt;transmisic sui-bait&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;The &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805192514/https://fluf.club/about&#34;&gt;instance &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; recommends freespeechextremist.com and kiwifarms.cc as instances &amp;ldquo;with similar moderation policies&amp;rdquo;; both those instances are on FediNuke with receipts.&lt;/dd&gt;
&lt;dt id=&#34;foxgirl&#34; tabindex=&#34;-1&#34;&gt;foxgirl.lol&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231225070141/https://freespeechextremist.com/notice/Ad8mJ08CxEkH8APY9o&#34;&gt;Blatantly antisemitic use of slurs from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231225070742/https://freespeechextremist.com/notice/Ad33CMpHuq0UPsrYYa&#34;&gt;transmisic slurs from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;freak-uni&#34; tabindex=&#34;-1&#34;&gt;freak.university OR pedo.school&lt;/dt&gt;
&lt;dd&gt;Instance known for permitting paraphilia including pedophilia, and also explicitly allows minors (13+ although &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.02-041801/https://freak.university/@headmasters/110743455953705070&#34;&gt;that limit may be lowered&lt;/a&gt;). Scroll through local users on &lt;code&gt;/directory&lt;/code&gt; for more receipts.&lt;/dd&gt;
&lt;dd&gt;pedo.school &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.10-032721/https://pedo.school/about&#34;&gt;has identical rules on its &amp;ldquo;About&amp;rdquo; page&lt;/a&gt;. Instance contains untagged sexual depictions of minors and multiple self-described &amp;ldquo;pro-c&amp;rdquo; users; scroll through local users on &lt;code&gt;/directory&lt;/code&gt; for more receipts.&lt;/dd&gt;
&lt;dt id=&#34;freeatlantis&#34; tabindex=&#34;-1&#34;&gt;freeatlantis.com&lt;/dt&gt;
&lt;dd&gt;Far-right MAGA instance.&lt;/dd&gt;
&lt;dd&gt;Admin has reblogged local users posting &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.26-070739/https://freeatlantis.com/@TXPatriot2021/110527351920294198&#34;&gt;extreme transmisogny&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.26-070937/https://freeatlantis.com/@Luther/110334945481724374&#34;&gt;xenomisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.26-070756/https://freeatlantis.com/@waronmorons/110288183334646071&#34;&gt;anti-drag&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.26-070803/https://freeatlantis.com/@watson/110137469656072122&#34;&gt;MAGA&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/2024.05.26-070810/https://freeatlantis.com/@watson/109743198074918647&#34;&gt;anti-vax&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.26-070817/https://freeatlantis.com/@Phil/109693908947686128&#34;&gt;more anti-vax&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.26-071103/https://freeatlantis.com/@surferistic/109733973331065745&#34;&gt;QAnon&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;fse&#34; tabindex=&#34;-1&#34;&gt;freespeechextremist.com OR fsebugoutzone.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230628203218/https://1611.social/@StarProphet@freespeechextremist.com/posts/AXA3GP4cXfijajukpU&#34;&gt;End of this thread&lt;/a&gt; has blatant antisemitism.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802003611/https://eientei.org/notice/AYEtXJ1Dea4cIBV488&#34;&gt;Multiple other users engaging in transmisogyny&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-154818/https://freespeechextremist.com/notice/AYMCBqcaPUmd6J0ho8&#34;&gt;participating in a transmisogynistic harassment campaign&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803185746/https://freespeechextremist.com/notice/AYJ1aYy7Uutycamkuu&#34;&gt;Transmisic blanket-pedojacketing&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;MRF policies include a &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731164723/https://freespeechextremist.com/about&#34;&gt;block-notification bot&lt;/a&gt;. The linked page also makes it clear that this is a freeze-peach instance, so reporting won&amp;rsquo;t help.&lt;/dd&gt;
&lt;dd&gt;In April 2024, FSE migraterd to fsebugoutzone.org due to technical issues. &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/dPeoa&#34;&gt;Blog post&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/gYiL1&#34;&gt;new matching admin profile&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/ZQtJj&#34;&gt;new &amp;ldquo;about&amp;rdquo; page&lt;/a&gt;. The MRF policies listed include rejecting deletes, block-notification, and a freeze-peach moderation policy.&lt;/dd&gt;
&lt;dt id=&#34;froth&#34; tabindex=&#34;-1&#34;&gt;froth.zone&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-004755/https://froth.zone/notice/AQAJYgb2fjf0bEhbvs&#34;&gt;Blatant racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-004725/https://froth.zone/notice/AQA5cC86URWDuOwgYi&#34;&gt;racist homomisia&lt;/a&gt;. Reporting is unlikely to help given the lack of rules against this, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803161348/https://froth.zone/notice/AVFLzUfMMCZGqnTm8e&#34;&gt;some ableism from the admin&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803161352/https://froth.zone/notice/AVFRa00PoXEWFDYR2u&#34;&gt;some racism from the admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;gameliberty&#34; tabindex=&#34;-1&#34;&gt;gameliberty.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/ir4hc&#34;&gt;Freeze-peach rules&lt;/a&gt; permit lolisho, which may be a legal risk depending on your jurisdiction.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/x9xUe&#34;&gt;Admin pinned posts&lt;/a&gt; contain slurs in un-reclaimed contexts, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://gameliberty.club/@dailyslurbot&#34;&gt;runs an rsdb bot&lt;/a&gt; for more.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://gameliberty.club/@matrix/110691184671379555&#34;&gt;posts racist memes&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://gameliberty.club/@matrix/110691000630024399&#34;&gt;more racist memes&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://gameliberty.club/@matrix/110705822988959149&#34;&gt;anti-pride&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;gearlandia&#34; tabindex=&#34;-1&#34;&gt;gearlandia.haus&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805034502/https://gearlandia.haus/notice/AY8D5ossGoV9B7Eria&#34;&gt;Transmisic targeted harassment from multiple staff members&lt;/a&gt;, including sui-bait.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805035409/https://gearlandia.haus/notice/AVBWXlFGHdqqogRnmK&#34;&gt;Racist use of slurs from another staff member&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804224636/https://gearlandia.haus/notice/AV5ogisR5efiIwQzKa&#34;&gt;Assorted queermisia from multiple users, including staff&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Staff members sometimes post lolisho, which may pose a legal risk in some jurisdictions.&lt;/dd&gt;
&lt;dt id=&#34;geofront&#34; tabindex=&#34;-1&#34;&gt;geofront.rocks&lt;/dt&gt;
&lt;dd&gt;Well-known Nazi instance.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802234620/https://geofront.rocks/notice/AYKO5jmR77AB8nBtZo&#34;&gt;Blatantly racist and transmisic use of slurs&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802234722/https://geofront.rocks/notice/AYJDETasJd7SUuuS4O&#34;&gt;ethno-nationalism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/RGPfP&#34;&gt;more racism&lt;/a&gt;. All from what seems to be the primary active user of the instance.&lt;/dd&gt;
&lt;dd&gt;Another user has a &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802235236/https://geofront.rocks/@flux&#34;&gt;blatantly Nazi profile&lt;/a&gt; featuring violent transmisic shock content.&lt;/dd&gt;
&lt;dt id=&#34;genderheretics&#34; tabindex=&#34;-1&#34;&gt;genderheretics.xyz&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804235043/https://genderheretics.xyz/about&#34;&gt;&amp;ldquo;About&amp;rdquo; page explicitly labels the instance as transmisic&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/wlQdv&#34;&gt;posts unmarked NSFL medical gore&lt;/a&gt; in a transmisogynistic context.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805000311/https://genderheretics.xyz/@william/posts/AYFfRi8X3hx6nJOaXY&#34;&gt;Anti-drag pedojacketing&lt;/a&gt; from admin.&lt;/dd&gt;
&lt;dt id=&#34;gleasonator&#34; tabindex=&#34;-1&#34;&gt;gleasonator.com&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2022.08.07-110329/https://blog.alexgleason.me/trans/&#34;&gt;Admin is an outspoken TERF&lt;/a&gt;, who &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803181726/https://soapbox.pub/blog/soapbox-awarded-grant/&#34;&gt;was head of engineering for Truth Social&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;User &amp;ldquo;caekislove&amp;rdquo; &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-190023/https://gleasonator.com/notice/AYJ72Lm5gRlKpIEUJU&#34;&gt;pedojackets and sui-baits trans users&lt;/a&gt;, does &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803185742/https://freespeechextremist.com/notice/AYKvBEbxq0k2psshlY&#34;&gt;homomisic pedojacketing as well&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-190720/https://gleasonator.com/notice/AYL1K2K8WseIIv7xtg&#34;&gt;posts extreme classism&lt;/a&gt; (violent imagery).&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803184758/https://annihilation.social/notice/AWfGcY4mrHiPL3mgfQ&#34;&gt;Admin is aware of the user but will not take action&lt;/a&gt; (unrelated extreme bigotry and Nazi iconography in thread).&lt;/dd&gt;
&lt;dt id=&#34;getgle&#34; tabindex=&#34;-1&#34;&gt;glee.li&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/Vz1Yv&#34;&gt;Racist harassment of Mutual Aid posts&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;More &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/SI0xG&#34;&gt;blatant racism and transmisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803031028/https://glee.li/notice/AYG0asC42hyR8rld3I&#34;&gt;posts &lt;q&gt;glad shes gone&lt;/q&gt; in response to a gender and sexuality scholar dying&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-154818/https://freespeechextremist.com/notice/AYMCBqcaPUmd6J0ho8&#34;&gt;participates in a transmisogynistic harassment campaign&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805180006/https://glee.li/notice/AYQQrs1oS2HvwPKxJA&#34;&gt;More blatant racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Instance is associated with &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731045659/https://getgle.org/dark-mode.html&#34;&gt;the website https://getgle.org&lt;/a&gt;. Split off of asbestos.cafe in early 2023, formerly at a subdomain of getgle.org.&lt;/dd&gt;
&lt;dt id=&#34;goyim&#34; tabindex=&#34;-1&#34;&gt;goyim.social&lt;/dt&gt;
&lt;dd&gt;antisemitism, racism. All the following posts are from main user &amp;ldquo;Flatulenator&amp;rdquo;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.11-031159/https://nicecrew.digital/@Flatulenator@goyim.social/posts/AhhRup2INgYAzO0SXo&#34;&gt;Anti-Black racial caricatures&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.11-031504/https://freeatlantis.com/@icare4america/112385566195935930&#34;&gt;Antisemitic use of triple-parens&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.11-031238/https://freeatlantis.com/@DrFell/112409983151320233&#34;&gt;Anti-diversity white pride&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.is/2024.08.02-051621/https://annihilation.social/notice/AjX0DlDwJvOzQuv3kO&#34;&gt;Holocaust denial&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/RZaRq&#34;&gt;More blatant antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;harpy&#34; tabindex=&#34;-1&#34;&gt;harpy.faith&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240601010626/https://the.asbestos.cafe/notice/AiRpmLwX7zqBu1RbUm&#34;&gt;blatant antisemitism from admin&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240601010312/https://the.asbestos.cafe/notice/AiS7b5nabscfp02buC&#34;&gt;admin doubling down with racist slurs after being called out&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240601010728/https://the.asbestos.cafe/notice/AiRM6y5c0rLHNWbYeG&#34;&gt;Admin sends sui-bait transmisic replies to trans women&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240601005759/https://the.asbestos.cafe/notice/AiT35LJvA1iU2FjFvk&#34;&gt;suibait from user&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;h5q&#34; tabindex=&#34;-1&#34;&gt;h5q.net&lt;/dt&gt;
&lt;dd&gt;Contains untagged AI-generated photorealistic erotic content that may pose a legal risk in several jurisdictions.&lt;/dd&gt;
&lt;dt id=&#34;haeder&#34; tabindex=&#34;-1&#34;&gt;haeder.net&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230823231236/https://f.haeder.net/friendica&#34;&gt;Instance blocklist reasons are unapologetically queermisic&lt;/a&gt;, calling nonbinary individuals &amp;ldquo;delusional&amp;rdquo; and saying &lt;q&gt;We don&amp;rsquo;t need more diversity and tollerance when this doesn&amp;rsquo;t fall back on us straight people&lt;/q&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.23-235040/https://microblog.social/@roland@f.haeder.net&#34;&gt;Admin bio&lt;/a&gt; has blatant transmisia and hashtags such as &lt;q&gt;SayNoToWoke&lt;/q&gt;.&lt;/dd&gt;
&lt;dt id=&#34;hitchhiker&#34; tabindex=&#34;-1&#34;&gt;hitchhiker.social OR battlepenguin.video&lt;/dt&gt;
&lt;dd&gt;Sibling instances of djsumdog.com, run by the same admin; see its entry.&lt;/dd&gt;
&lt;dt id=&#34;idqqd&#34; tabindex=&#34;-1&#34;&gt;iddqd.social&lt;/dt&gt;
&lt;dd&gt;Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/1dIUL&#34;&gt;anti-Black caricatures&lt;/a&gt;, supports &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/PfHYX&#34;&gt;organized predatory retaliation against DEI efforts&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/0JlGl&#34;&gt;Instance landing page&lt;/a&gt; markets itself as an instance for 4chan users.&lt;/dd&gt;
&lt;dt id=&#34;kitsunemimi&#34; tabindex=&#34;-1&#34;&gt;kitsunemimi.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731183425/https://needs.vodka/notice/AYFCFHRqKX6RjsF7Fw&#34;&gt;Admin &amp;ldquo;bronze&amp;rdquo; participates in racist harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin sends users &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731184313/https://pl.kitsunemimi.club/notice/AYG5j6YeP0wZI1jaPw&#34;&gt;transmisic shock content&lt;/a&gt;, makes &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819034201/https://pl.kitsunemimi.club/notice/AYqJSD3p46qj1BxsPY&#34;&gt;transmisic TTD posts with hashtag spam&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Runs the &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731183641/https://pl.kitsunemimi.club/about&#34;&gt;HighRoller MRF policy&lt;/a&gt; for a block-notification bot.&lt;/dd&gt;
&lt;dt id=&#34;kf&#34; tabindex=&#34;-1&#34;&gt;kiwifarms.cc&lt;/dt&gt;
&lt;dd&gt;The official occasionally-online &lt;a rel=&#34;nofollow&#34; href=&#34;https://www.cnet.com/culture/internet/kiwi-farms-what-to-know-about-the-hate-filled-message-forum-dropped-by-cloudflare/&#34;&gt;KiwiFarms&lt;/a&gt; Fediverse instance. Look up &amp;ldquo;KiwiFarms&amp;rdquo; online if you want receipts. It briefly came back once after a long period of downtime, so I&amp;rsquo;m not removing it during the current downtime.&lt;/dd&gt;
&lt;dt id=&#34;kyaruc&#34; tabindex=&#34;-1&#34;&gt;kyaruc.moe&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802182509/https://ak.kyaruc.moe/notice/AYHzrqQ7hXqfemWlfM&#34;&gt;sui-baiting to get on this list&lt;/a&gt;. Later changed their mind, got mad about being on it, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230813204417/https://boymoder.biz/notice/AYh9JolXzLgzlb9XGq&#34;&gt;publicized an attempted dox&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/mWst4&#34;&gt;Racist use of slurs&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802222537/https://clubcyberia.co/notice/AXtFrDv5xhLpVMHzqy&#34;&gt;targeted ableist harassment&lt;/a&gt;&lt;/dd&gt;
&lt;dt id=&#34;leafposter&#34; tabindex=&#34;-1&#34;&gt;leafposter.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731051338/https://cawfee.club/notice/AVS1llk6NOrAVPAB60&#34;&gt;Blatant antisemitism and queermisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731050932/https://leafposter.club/@Upsman/posts/AVS1ImJqDW5yEPcgwi&#34;&gt;SWERF&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731051017/https://leafposter.club/@Leaflord/posts/AVS04CFlPbegMpCOP2&#34;&gt;blatant racist use of slurs&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;liberdon&#34; tabindex=&#34;-1&#34;&gt;liberdon.com&lt;/dt&gt;
&lt;dd&gt;Freeze-peach ancap instance.&lt;/dd&gt;
&lt;dd&gt;Medical misinformation: &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143510/https://liberdon.com/@spinneria/111104720878148352&#34;&gt;COVIDspiracy&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143454/https://liberdon.com/@nosat/111112112220569150&#34;&gt;anti-vax&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143533/https://liberdon.com/@Rpallavicini/111103983187635747&#34;&gt;more anti-vax&lt;/a&gt;) across three different users.&lt;/dd&gt;
&lt;dd&gt;Across four users: &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143435/https://liberdon.com/@rimugu/111025931153300897&#34;&gt;transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143442/https://liberdon.com/@nosat/111118400907550652&#34;&gt;flat-earth conspiracy theories&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143450/https://liberdon.com/@aristoh4ck8r/111109158090162800&#34;&gt;antisemitism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-143502/https://liberdon.com/@aristoh4ck8r/111106321430714757&#34;&gt;blatant nazism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.24-144351/https://liberdon.com/@Rpallavicini/110768707732981452&#34;&gt;fashjacketing antifa&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;ligma&#34; tabindex=&#34;-1&#34;&gt;ligma.pro&lt;/dt&gt;
&lt;dd&gt;The admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/1CWNR&#34;&gt;threatened mass violence&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/lDbc0&#34;&gt;threatened animal cruelty&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/BJ4Iu&#34;&gt;posted unmarked gore (CW: NSFL gore)&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/fHnSg&#34;&gt;bragged about making death threats&lt;/a&gt;. After his infosec.exchange alt got banned he set up shop on fosstodon.org.&lt;/dd&gt;
&lt;dt id=&#34;loli-church&#34; tabindex=&#34;-1&#34;&gt;loli.church&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.20-055501/https://loli.church/notes/9k2rdrdih5&#34;&gt;Instance announcement post explicitly condones racist posts&lt;/a&gt; (reblogged by admin). Author of that post &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.20-060532/https://loli.church/notes/9kwsbbt8e8&#34;&gt;also posts blatant antisemitism&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.20-060735/https://loli.church/notes/9kmk1o2lwp&#34;&gt;anti-Indigenous ethno-nationalism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.20-053340/https://loli.church/notes/9k2si4ywl3&#34;&gt;loli.church is the new home of fediverse.dotnet00.dev&lt;/a&gt;. Receipts from the old instance: &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.01-163514/https://fediverse.dotnet00.dev/notes/9hugibpler&#34;&gt;Racist user &amp;ldquo;Wiz&amp;rdquo;&lt;/a&gt;, posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.01-191114/https://fediverse.dotnet00.dev/notes/9huygvr5jc&#34;&gt;edgy bigotry&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Receipts from the old instance: Reporting probably won&amp;rsquo;t help, as &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.01-174423/https://fediverse.dotnet00.dev/notes/97i5gzjd8n&#34;&gt;the admin maintains a freeze-peach policy&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.01-174611/https://fediverse.dotnet00.dev/notes/97nxwl75iy&#34;&gt;regularly boosts racist content themself&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;The users in receipts for &lt;code&gt;dotnet00.dev&lt;/code&gt; are now on &lt;code&gt;loli.church&lt;/code&gt; with the same handles. Their profiles contain uncensored loli hentai.&lt;/dd&gt;
&lt;dt id=&#34;lolicon-rocks&#34; tabindex=&#34;-1&#34;&gt;lolicon.rocks&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805183555/https://posting.lolicon.rocks/about&#34;&gt;&amp;ldquo;About&amp;rdquo; page&lt;/a&gt; states &lt;q&gt;posting.lolicon.rocks is a common carrier telecommunications provider that does not moderate content&lt;/q&gt; and also features the owner with the handle &amp;ldquo;BlinkRape&amp;rdquo;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-183749/https://posting.lolicon.rocks/BlinkRape&#34;&gt;Owner profile bio&lt;/a&gt; contains racist and ableist slurs.&lt;/dd&gt;
&lt;dd&gt;Owner &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-184903/https://posting.lolicon.rocks/notice/AYL1UBs25rFpSDuzY0&#34;&gt;posts antisemitism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805184950/https://posting.lolicon.rocks/notice/AYGVgyTLFFBIV1a6zI&#34;&gt;blatant racism in a climate-denial thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;lolison&#34; tabindex=&#34;-1&#34;&gt;lolison.network OR lolison.top&lt;/dt&gt;
&lt;dd&gt;Sibling instances focused on the MAP/pedophilia community. Claim to forbid CP, but also appears to have rules too lax for instances with such focus. Admin &amp;ldquo;Spag&amp;rdquo; also admins rapemeat.express; see its FediNuke entry.&lt;/dd&gt;
&lt;dt id=&#34;magicka&#34; tabindex=&#34;-1&#34;&gt;magicka.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.01.01-000040/https://mk.magicka.org/notes/9nxpu35bjwd608ne&#34;&gt;antisemitism from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.01.01-000105/https://mk.magicka.org/notes/9nxpx8fajwd608nr&#34;&gt;unreclaimed use of homomisic slur&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.01.01-000355/https://mk.magicka.org/notes/9nw96fr2jwd607lm&#34;&gt;climate change denial conspiracy theories&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.01-011504/https://mk.magicka.org/notes/9tt2ecthxjq600t3&#34;&gt;anti-abortion&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;marsey&#34; tabindex=&#34;-1&#34;&gt;marsey.moe OR taihou.website&lt;/dt&gt;
&lt;dd&gt;boks.moe had &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/ozeh1&#34;&gt;the occasional holocaust denial meme&lt;/a&gt;. one of the main users &amp;ldquo;Ruusu&amp;rdquo; set their display name to &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/ANM7B&#34;&gt;a racial slur in a violent context&lt;/a&gt;. Staff member &amp;ldquo;MischievousuTomatosu&amp;rdquo; posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/WP9mb&#34;&gt;blatantly racist takes on border control&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730191654/https://shitposter.club/notice/AX3ZOWyu6dX384tV32&#34;&gt;boks.moe moved to marsey.moe&lt;/a&gt;, which features a &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/2dTWR&#34;&gt;hitler-themed racist &amp;ldquo;Witster_&amp;rdquo; account&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/Uri4S&#34;&gt;making fun of mutual aid posts&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804231317/https://marsey.moe/notice/AXyBmu2bgZCX3hTp2G&#34;&gt;racist misogyny&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.12-192245/https://marsey.moe/notice/AYduTzUXJ5bwlIBkQK&#34;&gt;blatantly transmisic jokes&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Staff member &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231228001500/https://5dollah.click/notice/Ad2xwISZPH2lfgprMm&#34;&gt;later moved to taihou.website&lt;/a&gt;. The staff member then went on to post &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.12.28-001750/https://rebased.taihou.website/notice/Ad6aKh8SogLOrXocXA&#34;&gt;rape threats&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231228212535/https://5dollah.click/notice/AdFx25iI8W92yerpOC&#34;&gt;anti-vax&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231228213012/https://5dollah.click/notice/AdH6xZc8jRYUxsQyxM&#34;&gt;indomisic racism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231229202055/https://5dollah.click/notice/AdJKrnOyLPU7fBKmhc&#34;&gt;some more xenomisia&lt;/a&gt;&lt;/dd&gt;
&lt;dt id=&#34;merovingian&#34; tabindex=&#34;-1&#34;&gt;merovingian.club&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805223728/https://merovingian.club/about/more&#34;&gt;Instance &amp;ldquo;About&amp;rdquo; page&lt;/a&gt; bills it as &amp;ldquo;a club for redpilled exiles&amp;rdquo;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805224237/https://merovingian.club/@Tfmonkey&#34;&gt;is active on MGTOW.TV&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805224237/https://merovingian.club/@Tfmonkey&#34;&gt;posts racist caricatures&lt;/a&gt;. Admin and instance members &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805225705/https://merovingian.club/@Tfmonkey/110738753148280235&#34;&gt;are deeply misogynistic&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805225652/https://merovingian.club/@Tfmonkey/110811121187917572&#34;&gt;Another example of admin misogyny&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Among users, there&amp;rsquo;s &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805225541/https://merovingian.club/@ButtWorldsMan/110827637731366197&#34;&gt;blatant transmisogyny&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805225614/https://merovingian.club/@37712/110835564287021760&#34;&gt;antisemitism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805225448/https://merovingian.club/@AKEmon869/109948185254841658&#34;&gt;anti-vax&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;midwaytrades&#34; tabindex=&#34;-1&#34;&gt;midwaytrades.com&lt;/dt&gt;
&lt;dd&gt;Runs &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802162551/https://freesoftwareextremist.com/notice/AYBwS5rDjFaDyIqKtU&#34;&gt;a Libs of TikTok bot&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/9qO8r&#34;&gt;Transmisic and misogynist admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;mirr0r&#34; tabindex=&#34;-1&#34;&gt;mirr0r.city&lt;/dt&gt;
&lt;dd&gt;Paraphilia- and pedophilia-focused instance that &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230828183201/https://mirr0r.city/notice/AVr8KfJybjh4eFdHAO&#34;&gt;explicitly welcomes pro-contacts and neo-Nazis&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;mouse-services&#34; tabindex=&#34;-1&#34;&gt;mouse.services&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.19-042746/https://miss.mouse.services/notes/9ijlonbgrd&#34;&gt;posts blatantly racist use of slurs&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.19-054501/https://miss.mouse.services/notes/9icb5d8xav&#34;&gt;more racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;morale&#34; tabindex=&#34;-1&#34;&gt;morale.ch&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-163829/https://morale.ch/notes/9gq5de3opm&#34;&gt;Transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-163438/https://morale.ch/notes/99afbs2fi7&#34;&gt;blatant antisemitism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-163416/https://morale.ch/notes/99afgfh0il&#34;&gt;both at once&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-165106/https://morale.ch/notes/9fhmfgittd&#34;&gt;Ableist holocaust denial&lt;/a&gt;. All from the admin account.&lt;/dd&gt;
&lt;dt id=&#34;mugicha&#34; tabindex=&#34;-1&#34;&gt;mugicha.club&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803192951/https://strelizia.net/notice/AY89eVVq0KBnBANq3k&#34;&gt;participated in a transmisic targeted harassment campaign&lt;/a&gt; with local users.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803192115/https://strelizia.net/notice/AYMZTqabCh9ZBRZFU8&#34;&gt;Anti-asian racist slurs from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803192548/https://strelizia.net/notice/AYIxpdSJqqonI55f0q&#34;&gt;Misogynistic racism from admin&lt;/a&gt; with several local users with Confederate battle-flags in their display names.&lt;/dd&gt;
&lt;dd&gt;More &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803192732/https://strelizia.net/notice/AYCAY6fkm4FiXMrv8K&#34;&gt;blatantly racist use of slurs from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;natehiggers&#34; tabindex=&#34;-1&#34;&gt;natehiggers.online&lt;/dt&gt;
&lt;dd&gt;Used to run an awful Pleroma instance, which shut down. A WriteFreely instance is still up on the &amp;ldquo;wf&amp;rdquo; subdomain. Domain name is an obvious &lt;a rel=&#34;nofollow&#34; href=&#34;https://www.wordnik.com/words/spoonerism&#34;&gt;spoonerism&lt;/a&gt; of racist use of slurs.&lt;/dd&gt;
&lt;dd&gt;The WriteFreely blog features &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806204753/https://wf.natehiggers.online/pfizer-loves-to-mutate-viruses-for-fun-and-profit&#34;&gt;COVID conspiracy theories&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806205054/https://wf.natehiggers.online/lizard-person-and-new-zealands-first-trans-gendered-prime-minister-suddenly&#34;&gt;violent racist transmisogyny&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806205719/https://wf.natehiggers.online/one-world-government-eu-and-us-cdc-both-authorize-giving-con-vid-injections-to&#34;&gt;anti-vax&lt;/a&gt;, and other far-right content.&lt;/dd&gt;
&lt;dt id=&#34;narrativerry&#34; tabindex=&#34;-1&#34;&gt;narrativerry.xyz&lt;/dt&gt;
&lt;dd&gt;Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808151934/https://pleroma.narrativerry.xyz/notice/AY8awZ3lCW2pXp6TWi&#34;&gt;blatant anti-Indian racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808153236/https://annihilation.social/notice/AXyTzERY59CX89mqn2&#34;&gt;combines antisemitic conspiracy theories, homomisia, and racism in a slur-filled thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;nobodyhasthebiz&#34; tabindex=&#34;-1&#34;&gt;nobodyhasthe.biz OR nationalist.social&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812043648/https://pleroma.nobodyhasthe.biz/about&#34;&gt;&amp;ldquo;About&amp;rdquo; page&lt;/a&gt; lists multiple admins and mods with swastikas in their display names and/or profile photos.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812044221/https://pleroma.nobodyhasthe.biz/notice/AXrR8x4yddPB9nEKrQ&#34;&gt;Admin &amp;ldquo;ShariVegas&amp;rdquo; is an unapologetic white supremacist&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.12-044406/https://pleroma.nobodyhasthe.biz/objects/d1ce538f-3788-448c-a74f-7e2ab7a4db75&#34;&gt;antisemite&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812044743/https://pleroma.nobodyhasthe.biz/notice/APJkc4Ju9vntVMVLiy&#34;&gt;Admin &amp;ldquo;thomaslewis&amp;rdquo; makes fun of a report against a blatantly racist user&lt;/a&gt; while adding a homomisic and antisemitic slur of his own.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812191733/https://pleroma.nobodyhasthe.biz/BobRoss&#34;&gt;Moderator &amp;ldquo;BobRoss&amp;rdquo; has a bio starting with &lt;q&gt;Spreading the joy of antisemitism&lt;/q&gt;&lt;/a&gt; and encourages calling users slurs instead of reporting as &lt;q&gt;an integral part of the culture around here&lt;/q&gt;.&lt;/dd&gt;
&lt;dd&gt;nobodyhasthe.biz eventually migrated to nationalist.social. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.15-195940/https://nationalist.social/@thomas/posts/AbmS8a2es8aS2giTy4&#34;&gt;Instance announcement establishes the connection&lt;/a&gt;. Contains the same/similar staff handles.&lt;/dd&gt;
&lt;dd&gt;Some local users on the new instance: &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.15-200939/https://nationalist.social/@NateHiggers1488&#34;&gt;a self-identified racist with nazi iconography&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.15-200737/https://nationalist.social/@nike/posts/Abpuph0qDAPoIw5mT2&#34;&gt;a blatantly antisemitic white nationalist&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.15-200150/https://nationalist.social/@thomas/posts/AboHPaZzPrl5S98PCa&#34;&gt;Admins of nationalist.social made it clear that reporting won&amp;rsquo;t help&lt;/a&gt;, if you&amp;rsquo;re still holding out hope for some reason.&lt;/dd&gt;
&lt;dt&gt;peertube.se {peertube-se}&lt;/dt&gt;
&lt;dd&gt;Instance &lt;a rel=&#34;nofollow&#34; href=&#34;http://archive.today/2025.07.01-204007/https://peertube.se/c/motstandsmedia_shorts/videos?s=1&#34;&gt;self-affiliates with the Nordic Resistance Movement&lt;/a&gt;. This is the main active account on the instance.&lt;/dd&gt;
&lt;dt id=&#34;ssr&#34; tabindex=&#34;-1&#34;&gt;shortstacksran.ch OR needs.vodka&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731171924/https://needs.vodka/notice/AYEXL71RuRXt1MYkSG&#34;&gt;posts ethno-fascist harassment&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731172003/https://needs.vodka/notice/AYE2Y0GlEONjGKO8dk&#34;&gt;antisemitism&lt;/a&gt;. Supports &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731172555/https://needs.vodka/notice/AYAgwij0ohSdci6UjI&#34;&gt;racist, misogynistic, violent grooming&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;shortstacksran.ch is the continuation of squid.kids and shortstackran.ch (note the extra &amp;ldquo;s&amp;rdquo;), by the same admin. &lt;a rel=&#34;nofollow&#34; href=&#34;https://pleroma.envs.net/notice/ARU20uCgVwHeewEm6S&#34;&gt;See prior FediBlock post&lt;/a&gt;. On the new instance, the admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230811200737/https://shortstacksran.ch/notice/AYbjnyIOQ5ZYOpQtaC&#34;&gt;extremely racist use of slurs&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230811200824/https://shortstacksran.ch/notice/AYbeUcILUiKOtOMWVE&#34;&gt;racist antisemitism&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230827224843/https://shortstacksran.ch/notice/AZ4J3H3mYPXYtiWcdM&#34;&gt;Blatantly racist use of slurs and hashtag-spam&lt;/a&gt; in a block-bait post from a local user.&lt;/dd&gt;
&lt;dt id=&#34;nicecrew&#34; tabindex=&#34;-1&#34;&gt;nicecrew.digital&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731154105/https://nicecrew.digital/notice/AT5UuihBpC4ZI8xIlk&#34;&gt;Blatant anti-Black racism from staff&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731153949/https://nicecrew.digital/notice/AYCsMzQsKax7qc0b1E&#34;&gt;anti-Black racist caricature from staff&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731160204/https://nicecrew.digital/notice/AY4YmRWar1CMk4usOO&#34;&gt;Antisemitic COVIDspiracy from staff&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Has &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-153949/https://nicecrew.digital/@nice-nigger&#34;&gt;a bot to spam threads with racist slurs&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;nightshift&#34; tabindex=&#34;-1&#34;&gt;nightshift.social&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/Z6hC4?wr=false&#34;&gt;Anti-Black racism and antisemitism from staff&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/Dfln4&#34;&gt;Extreme anti-black racism&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/kAK8G&#34;&gt;more antisemitism&lt;/a&gt; from another staff member.&lt;/dd&gt;
&lt;dt&gt;nnia.cc OR nnia.space {#nnia}&lt;/dt&gt;
&lt;dd&gt;Paraphile pro-zoo pro-MAP instance that also allows both minors and pro-contact users to register. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819210233/https://nnia.space/@scramblecore/110910301694831861&#34;&gt;Pro-C zoosexuality&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;nnia.cc is a newer instance that &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231104224647/https://nnia.cc/about&#34;&gt;claims to be a continuation of nnia.space&lt;/a&gt;. It also claims to have closed federation, but I included it alongside nnia.space should that ever change, since I can&amp;rsquo;t imagine that FediNuke users would wish to federate with it anyway.&lt;/dd&gt;
&lt;dt id=&#34;nas&#34; tabindex=&#34;-1&#34;&gt;noagendasocial.com&lt;/dt&gt;
&lt;dd&gt;Far-right instance connected to the No Agenda show.&lt;/dd&gt;
&lt;dd&gt;Blatant &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/Km8Ju&#34;&gt;queermisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;One of its more popular users is &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731165314/https://noagendasocial.com/@amerika&#34;&gt;openly an ethno-nationalist&lt;/a&gt; with &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731165038/https://noagendasocial.com/@amerika/110652580178110907&#34;&gt;thinly-veiled genocidal views&lt;/a&gt; and runs the far-right amerika.org blog.&lt;/dd&gt;
&lt;dd&gt;An even more popular user &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731165844/https://noagendasocial.com/@furgar/110558690945902519&#34;&gt;regularly posts far-right content&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;nasnl&#34; tabindex=&#34;-1&#34;&gt;noagendasocial.nl OR noagendatube.com&lt;/dt&gt;
&lt;dd&gt;Sibling instances of noagendasocial.com, also connected to the No Agenda Show.&lt;/dd&gt;
&lt;dt id=&#34;noauthority&#34; tabindex=&#34;-1&#34;&gt;noauthority.social&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.02.16-052626/https://noagendasocial.com/@eriner&#34;&gt;Run by the admin of noagendasocial.com&lt;/a&gt; (&lt;a rel=&#34;nofollow&#34; href=&#34;#nas&#34;&gt;see the No Agenda Social FediNuke entry&lt;/a&gt;). Features &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.02.16-052700/https://noauthority.social/@eriner/111837215988394617&#34;&gt;more blatant transmisia from the admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.02.16-051953/https://noauthority.social/about&#34;&gt;Instance &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; describes it as a free-speech instance with a link to &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240216052134/https://freezepeach.social/&#34;&gt;a directory of other instances with similar policies&lt;/a&gt;; all the live domains on that list are also on FediNuke with receipts.&lt;/dd&gt;
&lt;dt id=&#34;norwoodzero&#34; tabindex=&#34;-1&#34;&gt;norwoodzero.net&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803155542/https://norwoodzero.net/notice/AYME53gDdYuiYrDxtQ&#34;&gt;pedojackets in a transmisic harassment campaign&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230807201105/https://norwoodzero.net/notice/AYTiBWAQFwxg3WuJv6&#34;&gt;invites others users for the purpose of harassing trans users&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812041051/https://norwoodzero.net/notice/AYdS8m9yyTQAKCUfy4&#34;&gt;Another example, using the fact that the instance is &amp;ldquo;barely defederated&amp;rdquo; as a selling point&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803160235/https://norwoodzero.net/about&#34;&gt;Instance &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; contains racial slurs and an animated banner that says &amp;ldquo;whites only&amp;rdquo;.&lt;/dd&gt;
&lt;dt id=&#34;nyanide&#34; tabindex=&#34;-1&#34;&gt;nyanide.com&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810042952/https://lab.nyanide.com/notice/AYYjrpwtd8JLXZ2Z2u&#34;&gt;Staff member sends transmisogynistic pedojacketing harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Same &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810042358/https://shitposter.club/notice/AYYgsMhI2c3OcuelgO&#34;&gt;staff member posts blatant extreme racism (CW: SA)&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Same &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810042917/https://lab.nyanide.com/notice/AYYiuhMzspK1qc387c&#34;&gt;staff member sends anti-vax harassment to other users&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810043205/https://lab.nyanide.com/notice/AYWCxeOho0ZKeFICSe&#34;&gt;Two staff members in a racist and antisemitic thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;onionfarms&#34; tabindex=&#34;-1&#34;&gt;onionfarms.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806210051/https://onionfarms.org/about&#34;&gt;&amp;ldquo;About&amp;rdquo; page&lt;/a&gt; says &lt;q&gt;This is a Mastodon server for the Onionfarms and Kiwifarms communites&lt;/q&gt; [sic] and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806210312/https://onionfarms.org/@admin&#34;&gt;admin bio confirms it&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;pawlicker&#34; tabindex=&#34;-1&#34;&gt;pawlicker.com&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230825211851/https://www.pawlicker.com/essays/troonshine.html&#34;&gt;Root domain hosts a pro-KiwiFarms and transmisic essay&lt;/a&gt;. Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/eL15z&#34;&gt;posts transmisogyny&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.25-214543/https://seal.cafe/@PhenomX6@fedi.pawlicker.com/posts/AXWOTf5oJdrZo2EvtQ&#34;&gt;more transmisia&lt;/a&gt; (the person he references knowing more is a KF staff member), &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.25-215639/https://seal.cafe/@PhenomX6@fedi.pawlicker.com/posts/AXWN3ovZ1nkUpBYqpM&#34;&gt;even more transmisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;pawoo&#34; tabindex=&#34;-1&#34;&gt;pawoo.net&lt;/dt&gt;
&lt;dd&gt;Lolisho instance that does not moderate sufficiently. Has had several incidents of actual CSAM and child predators going unmoderated for long durations, despite reports.&lt;/dd&gt;
&lt;dt id=&#34;parcero&#34; tabindex=&#34;-1&#34;&gt;parcero.bond OR parcero.casa&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231228002424/https://parcero.bond/notice/AdFAk7TtAOSWOdVTTE&#34;&gt;Blatantly racist slur use from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.12.28-002727/https://parcero.bond/notice/AdE0tKsBYHTBpxfQ5Q&#34;&gt;Antisemitism from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231228002906/https://parcero.bond/notice/AdDoer14YwYJja9V5s&#34;&gt;Sui-bait from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;New domains included &lt;code&gt;mi.parcero.casa&lt;/code&gt; and &lt;code&gt;ti.parcero.casa&lt;/code&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;http://archive.today/2024.12.06-185231/https://mi.parcero.casa/post/01939d0c-afc7-a56b-e1d5-b91b2d2b1a91&#34;&gt;Admin endorsed transmisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;piazza&#34; tabindex=&#34;-1&#34;&gt;piazza.today&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.01-014811/https://piazza.today/@centurion/posts/AhvMSBKb1Bsa1jNXAO&#34;&gt;climate denial from admin&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/ptplK?wr=false&#34;&gt;COVID misinformation from admin&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/4gdb9?wr=false&#34;&gt;transmisia from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.01-014633/https://piazza.today/@KeineAngstVorOffenenDiskussionen/posts/AhelEioEQVRDb1Jw24&#34;&gt;xenomisic MAGA crap&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.01-015727/https://piazza.today/@KeineAngstVorOffenenDiskussionen/posts/AguHJTpzkvKNoTW5NA&#34;&gt;Great Replacement conspiracy theories&lt;/a&gt; (archive visually cut off, but the post is visible in the screenshot tab or in page source code) from local user.&lt;/dd&gt;
&lt;dt id=&#34;pibvt&#34; tabindex=&#34;-1&#34;&gt;pibvt.net&lt;/dt&gt;
&lt;dd&gt;Lolisho and actual photos of toddlers posted by MAPs. &lt;a rel=&#34;nofollow&#34; href=&#34;https://pleroma.envs.net/notice/AS9QjlcEaQgZKbz5gO&#34;&gt;FediBlock post&lt;/a&gt; with some more details.&lt;/dd&gt;
&lt;dt id=&#34;pieville&#34; tabindex=&#34;-1&#34;&gt;pieville.net&lt;/dt&gt;
&lt;dd&gt;Admin is a white nationalist who &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.19-214916/https://pieville.net/@Alex_Linder/110882938852628318&#34;&gt;supports building an ethno-state, and genocide&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819215516/https://pieville.net/@Alex_Linder&#34;&gt;Admin profile&lt;/a&gt; features more blatant slur-filled racism, antisemitism, etc.&lt;/dd&gt;
&lt;dt id=&#34;poast&#34; tabindex=&#34;-1&#34;&gt;poa.st&lt;/dt&gt;
&lt;dd&gt;Well-known Nazi instance. See receipts for needs.vodka, kitsunemimi.club, and shitpost.cloud for poast users. Also see &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.02.21-072914/https://poa.st/notice/Aez6vYIX8PuuRpoKpM&#34;&gt;this Poast thread containing unapologetic racism, transmisia, and other bigotry from the Poast admin and users&lt;/a&gt; volunteering receipts for this resource.&lt;/dd&gt;
&lt;dt id=&#34;poast-org&#34; tabindex=&#34;-1&#34;&gt;poast.org OR poast.tv&lt;/dt&gt;
&lt;dd&gt;Instances affiliated with poa.st.&lt;/dd&gt;
&lt;dt id=&#34;pisskey&#34; tabindex=&#34;-1&#34;&gt;pisskey.io OR sad.cab&lt;/dt&gt;
&lt;dd&gt;Graf, admin of poa.st, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.23-010514/https://pisskey.io/notes/967qzpya6e&#34;&gt;also runs (and block-evades from) pisskey.io&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.23-171937/https://pisskey.io/notes/975lgwb22i&#34;&gt;sends racist transmisic antisemitic harassment&lt;/a&gt; from it too.&lt;/dd&gt;
&lt;dd&gt;Also &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.23-171431/https://sad.cab/graf&#34;&gt;runs sad.cab&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;poster-place&#34; tabindex=&#34;-1&#34;&gt;poster.place&lt;/dt&gt;
&lt;dd&gt;Staff member &amp;ldquo;spitfire&amp;rdquo; &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730195759/https://breastmilk.club/notice/AWy4STyPAWSj5e0SYq&#34;&gt;spams the &amp;ldquo;mutualaid&amp;rdquo; guppe group and hashtag with extreme queermisia&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230803191342/https://poster.place/notice/AYKzM8YDhgDVhxcsaG&#34;&gt;makes racist homomisic slur-filled anti-antifa posts&lt;/a&gt;. Instance header contains an animated GIF full of slurs.&lt;/dd&gt;
&lt;dt id=&#34;rms&#34; tabindex=&#34;-1&#34;&gt;rapemeat.solutions OR rapemeat.express&lt;/dt&gt;
&lt;dd&gt;rapemeat.solutions is the successor to hentai.baby, run by its admin. hentai.baby was known for posting real CSA material. Openly pro-CSA. Has drawn nudity in the instance background.&lt;/dd&gt;
&lt;dd&gt;rapemeat.express is the more public counterpart to rapemeat.solutions according to &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230813060551/https://rapemeat.express/about&#34;&gt;its &amp;ldquo;About&amp;rdquo; page&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;raycist&#34; tabindex=&#34;-1&#34;&gt;rayci.st&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810044615/https://clubcyberia.co/notice/AYPi3VK6AH4GUHkRua&#34;&gt;Admin posts racial slurs&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810045450/https://rayci.st/notice/AXmZFe2pzEX2de5ZfE&#34;&gt;anti-Indian racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810045536/https://rayci.st/notice/AXj1aII05WxPKYyaC8&#34;&gt;anti-Black racist use of slurs&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810050100/https://shitposter.club/notice/AXtq0w1YWMAapYudxQ&#34;&gt;some antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810045712/https://rayci.st/notice/AXcsEwPnK89XXciiRc&#34;&gt;Admin spams the MutualAid guppe group with shock content&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;rebelbase&#34; tabindex=&#34;-1&#34;&gt;rebelbase.site&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230814024949/https://rebelbase.site/notice/AX6t2x7AChyiuhFUsy&#34;&gt;posts blatant transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230814023544/https://rebelbase.site/notice/AYhQJk2zbUcyGiH82i&#34;&gt;posts more thinly-veiled transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230814025301/https://rebelbase.site/notice/AX1YsLPgYHR6DQmEgS&#34;&gt;insists on misgendering&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin is &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230814023633/https://rebelbase.site/notice/AYSDZeztvwDeSsgsbY&#34;&gt;anti-abortion&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230814023557/https://rebelbase.site/notice/AYfMikFnBX2q120e1Y&#34;&gt;identifies as an MRA&lt;/a&gt;.[^4]&lt;/dd&gt;
&lt;dd&gt;Elsewhere on the site is a user who posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230603013809/https://rebelbase.site/notice/ACAQrNpLxyWyYvDpke&#34;&gt;COVID denial&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230814030006/https://rebelbase.site/@Bram_Christiaens/posts/AR4TNA8GFndIBMEfz6&#34;&gt;anti-vax with a side of queermisia and Islamomisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;ryona&#34; tabindex=&#34;-1&#34;&gt;ryona.agency OR plagu.ee&lt;/dt&gt;
&lt;dd&gt;Admin bio features &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802203632/https://ryona.agency/mint&#34;&gt;blatant racism, antisemitism, misogyny, and other bigotry&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-154852/https://ryona.agency/notice/AYMBAB2LPVkH8l7vk0&#34;&gt;Admin participates in transmisogynistic harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/KoMXa&#34;&gt;Blatant racism from a local user&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;The &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802204037/https://ryona.agency/about&#34;&gt;instance &amp;ldquo;about page&amp;rdquo; features MRF policies&lt;/a&gt; to power a block-notification bot, to convert all posts (including followers-only posts) to public visibility, and to reject deletes.&lt;/dd&gt;
&lt;dd&gt;Also runs a version of Pleroma &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802204840/https://gitgud.io/ryonagency/pleroma/-/commit/d7fca9df32f4f083779371a3f843285188372ba6&#34;&gt;patched to allow bypassing authorized-fetch&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://pleroma.envs.net/notice/ATvo35BQNlDY9DQQue&#34;&gt;plagu.ee is run by the same admin as ryona.agency&lt;/a&gt;, with similar patches and MRF policies applied as per &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230410181459/https://plagu.ee/about&#34;&gt;the plagu.ee &amp;ldquo;about&amp;rdquo; page&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;schwartzwelt&#34; tabindex=&#34;-1&#34;&gt;schwartzwelt.xyz&lt;/dt&gt;
&lt;dd&gt;Admin participates in a transmisic harassment campaign by &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808021511/https://amala.schwartzwelt.xyz/notice/AY89V5Y55t9jdvpr9c&#34;&gt;posting transmisic pedojacketing[^5] sui-bait containing Nazi iconography&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808023622/https://amala.schwartzwelt.xyz/notice/AYTSo1vSMIZE2hKXB2&#34;&gt;More blatant transmisia from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808024805/https://amala.schwartzwelt.xyz/notice/AYMVgC61Pka5RUfjaS&#34;&gt;participates in anti-indigenous racist harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Local user &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808024312/https://amala.schwartzwelt.xyz/notice/AYRLX09MQtpO2D0lwe&#34;&gt;&amp;ldquo;Agartha_Noble&amp;rdquo; posts blatant racism&lt;/a&gt; in a thread about race-mixing.&lt;/dd&gt;
&lt;dt id=&#34;sc&#34; tabindex=&#34;-1&#34;&gt;seal.cafe&lt;/dt&gt;
&lt;dd&gt;Users including admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-231441/https://clubcyberia.co/notice/AYEajR8kZyASfOEtoO&#34;&gt;participate in transmisic targeted harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-232010/https://seal.cafe/notice/AYOtc7ux1QIVPNrgzg&#34;&gt;Racist slurs from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-233142/https://seal.cafe/notice/AYQ8TapnphkMxOo1Sa&#34;&gt;Antisemitic transmisia from a user&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230807202118/https://outdoors.lgbt/@ActuallyAubrey/110846065304916833&#34;&gt;Admin posting sui-bait in response to a trans woman coming out&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;shaw-app&#34; tabindex=&#34;-1&#34;&gt;shaw.app&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-135443/https://shaw.app/notes/9jpwpvgstpoxf5hl&#34;&gt;pedojackets trans people&lt;/a&gt;, posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-135442/https://shaw.app/notes/9j7y04uihayc4xgo&#34;&gt;blatant denial of trans validity&lt;/a&gt; (alongside other far-right talking points), and leaves &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-135533/https://shaw.app/notes/9jb1ayl0u3bi899q&#34;&gt;transmisic replies to trans women&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.10.02-135406/https://shaw.app/notes/9j96scd5b2y52za5&#34;&gt;Anti-mask post&lt;/a&gt; from admin.&lt;/dd&gt;
&lt;dt id=&#34;shitpost-cloud&#34; tabindex=&#34;-1&#34;&gt;shitpost.cloud&lt;/dt&gt;
&lt;dd&gt;Admin &amp;ldquo;Hoss&amp;rdquo; &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730000845/https://shitpost.cloud/notice/AXuj12Qs30YmatTqbo&#34;&gt;uses racial slurs in an unreclaimed context&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731062033/https://shitpost.cloud/notice/AYA2Obde8BUywbo45w&#34;&gt;publicized reports&lt;/a&gt; against local users participating in a targeted transmisic harassment campaign.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/5Vb2Q&#34;&gt;A user with a violent racist display name&lt;/a&gt;, with staff participating later in the thread.&lt;/dd&gt;
&lt;dt id=&#34;skinheads1&#34; tabindex=&#34;-1&#34;&gt;skinheads.social OR skinheads.eu&lt;/dt&gt;
&lt;dd&gt;The Antisocial Network is for white-nationalist skinhead subculture. &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/T8rZZ&#34;&gt;&amp;ldquo;Aryans&amp;rdquo; bot&lt;/a&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.06-214417/https://skinheads.eu/@ultras&#34;&gt;white pride&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.06-214448/https://skinheads.eu/@nordic&#34;&gt;Nordic resistance movement&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;skinheads2&#34; tabindex=&#34;-1&#34;&gt;skinheads.uk OR skinheads.io&lt;/dt&gt;
&lt;dd&gt;Alternate domains for The Antisocial Network.&lt;/dd&gt;
&lt;dt id=&#34;spinster&#34; tabindex=&#34;-1&#34;&gt;spinster.xyz OR neenster.org&lt;/dt&gt;
&lt;dd&gt;Spinster is a TERF instance created by Alex Gleason, admin of gleasonator.com; see its entry. Instance mostly engages in transmisogyny.&lt;/dd&gt;
&lt;dd&gt;Staff member &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/6kUM3&#34;&gt;posts blatant transmisogyny&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Another staff member &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.04.13-194916/https://spinster.xyz/@ninapaley&#34;&gt;openly admits to being a TERF in their profile&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;A third staff member &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.16-204546/https://spinster.xyz/notice/AIvseZMWKEEMu5ul96&#34;&gt;posts a rant against the validity of trans women&lt;/a&gt;, with several local members piling on in the replies.&lt;/dd&gt;
&lt;dd&gt;Neenster shares staff members (Alex Gleason, Nina Paley). The latter &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819205253/https://neenster.org/notice/AYlc7DIFkvKPPwgIka&#34;&gt;posts self-described TERF content&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.19-204435/https://blog.ninapaley.com/2023/02/07/he-ing-corinna/&#34;&gt;links to her blog with more TERF content&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;strelizia&#34; tabindex=&#34;-1&#34;&gt;strelizia.net&lt;/dt&gt;
&lt;dd&gt;Instance &amp;ldquo;About&amp;rdquo; page &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808161017/https://strelizia.net/about&#34;&gt;lists MRF policies to reject deletes and run a block-notification bot&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808164722/https://strelizia.net/notice/AYFGEQcTnNSkcuIa36&#34;&gt;posts anti-Black racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808164433/https://strelizia.net/notice/AY6JupLlwAlUJpprvc&#34;&gt;more blatant racism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808165632/https://strelizia.net/notice/AYCHMhIdT8w6L2YvD6&#34;&gt;some other slurs in non-reclaimed contexts&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;Local user &amp;ldquo;nikiboo&amp;rdquo; posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808181414/https://strelizia.net/notice/AXrIC2vJqLE5c296ps&#34;&gt;blatant anti-Black racism&lt;/a&gt; (re-blogged by admin), has a profile photo with Nazi imagery.&lt;/dd&gt;
&lt;dt id=&#34;subs4social&#34; tabindex=&#34;-1&#34;&gt;subs4social.xyz&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.07-044344/https://subs4social.xyz/notes/9u4v9dgx0l&#34;&gt;blatant antisemitism&lt;/a&gt; (transmisia further upthread if you view the canonical link).&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.07-044443/https://subs4social.xyz/notes/9u4s4rakro&#34;&gt;Misogyny and anti-Black racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.07-045502/https://subs4social.xyz/notes/9u4qo2ibo1&#34;&gt;more anti-Black racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.07-044545/https://subs4social.xyz/notes/9u4ovv3rjh&#34;&gt;Transmisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.06.07-045916/https://subs4social.xyz/notes/9u48ov3lu1&#34;&gt;Legitimizing fervor over white genocide by using it as a comparison to fervor over climate change&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;All receipts are from the only user to show up in the explore tab.&lt;/dd&gt;
&lt;dt id=&#34;tastingtraffic&#34; tabindex=&#34;-1&#34;&gt;tastingtraffic.net&lt;/dt&gt;
&lt;dd&gt;Admin account is a high-activity news account full of hashtag spam. Frequently posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.18-151425/https://tastingtraffic.net/@InternationalTechNews/111086792935014280&#34;&gt;far-right transmisia/queermisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230924135533/https://tastingtraffic.net/@InternationalTechNews/110968062234187455&#34;&gt;another example&lt;/a&gt;. The same content is frequently pasted in multiple posts per day.&lt;/dd&gt;
&lt;dt id=&#34;theblab&#34; tabindex=&#34;-1&#34;&gt;theblab.org&lt;/dt&gt;
&lt;dd&gt;Instance explicitly permits, and admin reblogs, openly ethno-nationalist/Nazi content from local users.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/AyVDy?wr=true&#34;&gt;TheBlab.org &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; says: &lt;q cite=&#34;https://theblab.org/about&#34;&gt;The Blab is the place for refugees of places that claim to be free speech. After the shekelcaust of Gab an alternative was needed. This is that alternative.&lt;/q&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/VKLRm?wr=true&#34;&gt;Admin profile page&lt;/a&gt; contains multiple reblogs of local users posting racial slurs, Nazi imagery, and antisemitism. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.03.22-120858/https://theblab.org/@Weaponized_Honesty/112134020761568654&#34;&gt;More racism from local users&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;thechimp-zone&#34; tabindex=&#34;-1&#34;&gt;thechimp.zone&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230811225851/https://thechimp.zone/notice/AYdPIQYHNfAO7u4C5Q&#34;&gt;sends transmisic pedojacketing harassment to trans users&lt;/a&gt;, with racial slurs to boot.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812013407/https://thechimp.zone/notice/AYXFLeLaNjVnI4GewK&#34;&gt;participates in queermisic harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230718054535/https://thechimp.zone/users/thegreatape&#34;&gt;Admin profile contains racial slurs&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;thenobody-club&#34; tabindex=&#34;-1&#34;&gt;thenobody.club&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230813033821/https://member.thenobody.club/notice/AYfZzC36XOLSbL4MyG&#34;&gt;participates in a transmisogynistic harassment campaign&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230813034819/https://member.thenobody.club/notice/AXwUlbbBVMnzu6VzG4&#34;&gt;Racist and antisemitic use of slurs from admin&lt;/a&gt;, along with some heavy xenomisia shortly after.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230813034920/https://member.thenobody.club/notice/AXsHtsJBBeQG0YrmBU&#34;&gt;More racist xenomisia from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;truthsocialcoin&#34; tabindex=&#34;-1&#34;&gt;truthsocial.co.in&lt;/dt&gt;
&lt;dd&gt;Named after Donald Trump&amp;rsquo;s &amp;ldquo;Truth Social&amp;rdquo; network. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230914234747/https://truthsocial.co.in/public/local&#34;&gt;A glimpse at their local timeline&lt;/a&gt; shows mostly far-right content befitting of the instance name. One of the main posters, &amp;ldquo;Kittruth&amp;rdquo;, regularly &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230914235535/https://truthsocial.co.in/@Kittruth/111065663686727434&#34;&gt;posts racist talking points&lt;/a&gt;. Instance seems completely unmoderated, with &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230915000055/https://truthsocial.co.in/@leoedward&#34;&gt;spambots such as &amp;ldquo;leoedward&amp;rdquo; going unnoticed for months&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;tsundere.love&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;http://archive.today/2025.07.01-211634/https://tsundere.love/Wiz?tab=statuses&#34;&gt;Admin profile&lt;/a&gt; lists them as an alt of a loli.church user, and has an alt called &amp;ldquo;wizgroomer&amp;rdquo; that posts sexually explicit lolicon.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2025.06.19-152117/https://tsundere.love/notice/AvI9vLtHmb5ExHgNgO&#34;&gt;Admin posts explicit anti-blackness&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/eGG03&#34;&gt;indomisic racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;usualsuspects&#34; tabindex=&#34;-1&#34;&gt;usualsuspects.lol&lt;/dt&gt;
&lt;dd&gt;Admin led &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/jjfV9&#34;&gt;targeted transmisic bodyshaming harassment&lt;/a&gt; against members of a mainly-trans instance. Originally created to be a &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230705053714/https://the.usualsuspects.lol/notice/AXKIqzKiWFFDNryNM0&#34;&gt;block-bait Soapbox instance&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;vampiremaid&#34; tabindex=&#34;-1&#34;&gt;vampiremaid.cafe&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.19-233105/https://vampiremaid.cafe/notice/AbjiluX5uvtvZBlFk8&#34;&gt;posts white nationalism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.19-234054/https://vampiremaid.cafe/notice/AbI9XvdcGiolHCUVGq&#34;&gt;blatant racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.19-232514/https://vampiremaid.cafe/notice/AbnqFr0D5HZ3cGRcRs&#34;&gt;antisemitism&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.19-235053/https://vampiremaid.cafe/notice/AbAjAG8qQYGx0EQntQ&#34;&gt;more racism and antisemitism&lt;/a&gt; with unreclaimed slurs.&lt;/dd&gt;
&lt;dd&gt;Admin posts &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.19-234110/https://vampiremaid.cafe/notice/AbL3pMUhedktF38CX2&#34;&gt;a context-free &amp;ldquo;HH&amp;rdquo;&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.19-234537/https://vampiremaid.cafe/notice/AbQhaXiob17tg11JmC&#34;&gt;boosts swastikas from Poast&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Note that the instance heavily features suggestive lolicon.&lt;/dd&gt;
&lt;dt id=&#34;varis&#34; tabindex=&#34;-1&#34;&gt;varishangout.net&lt;/dt&gt;
&lt;dd&gt;Instance permits lolicon/shotacon. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230729223647/https://varishangout.net/notice/AYBv4A9bwrZXfu0Hho&#34;&gt;sample non-graphic thread containing queermisia, esp. transmisia, with staff involvement&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230729225002/https://varishangout.net/notice/AYBmTghTBGJaGbw9zM&#34;&gt;another such thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230729234932/https://varishangout.net/notice/AYAXPrAAe2y35X7JFQ&#34;&gt;Staff member being openly transmisic&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730232126/https://varishangout.net/notice/AY7wuahlngicOwhlxo&#34;&gt;Several members participating in transmisic harassment&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;volk.network {volk} OR volk.love&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20250701205440/https://volk.network/@johnnydoomsayer&#34;&gt;Admin account&lt;/a&gt; has a bio of &amp;ldquo;White Power Alt-Tech&amp;rdquo; with a Nazi solute in his profile photo. Reblogs local users posting blatant antisemitism, and anti-blackness, and Nazi flags.&lt;/dd&gt;
&lt;dd&gt;volk.love is a PeerTube instance. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2025.07.01-210131/https://volk.love/about/instance/team&#34;&gt;Its &amp;ldquo;Team&amp;rdquo; page&lt;/a&gt; mentions the admin of volk.netowrk, links back to volk.network, and its description is blatantly white supremacist.&lt;/dd&gt;
&lt;dt id=&#34;vtuberfan&#34; tabindex=&#34;-1&#34;&gt;vtuberfan.social&lt;/dt&gt;
&lt;dd&gt;Racism and other hate-speech, CW for unmarked nudity in profile pictures and banners.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230726201042/https://vtuberfan.social/notice/AY0Vl0GncaKuVuYFwe&#34;&gt;Admin &amp;ldquo;Sivee&amp;rdquo; posts blatant racism&lt;/a&gt;, and local user &amp;ldquo;Saige&amp;rdquo; replies with violent racist bait. Sivee likely went by the same handle on &lt;code&gt;seal.cafe&lt;/code&gt;.&lt;/dd&gt;
&lt;dd&gt;Saige &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230726201224/https://vtuberfan.social/notice/AY1h5fIkwcCpslSSlU&#34;&gt;posts homomisic bait&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;wolfgirl&#34; tabindex=&#34;-1&#34;&gt;wolfgirl.bar&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731171233/https://needs.vodka/notice/AYFBR71kngKIwM7Moa&#34;&gt;participates in racist harassment&lt;/a&gt;, posting &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731170555/https://wolfgirl.bar/notice/AUj1Rrjrtm87kjCF9c&#34;&gt;openly Nazi bigoted slur-filled content&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731190102/https://wolfgirl.bar/notice/AYCbKZqp4ty1mhrJE8&#34;&gt;Sends Nazi imagery with racial slurs to Jewish users&lt;/a&gt; while defending slavery.&lt;/dd&gt;
&lt;dt id=&#34;yggdrasil&#34; tabindex=&#34;-1&#34;&gt;yggdrasil.social&lt;/dt&gt;
&lt;dd&gt;The first rule of &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819213623/https://yggdrasil.social/about&#34;&gt;the yggdrasil.social &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; says &amp;ldquo;No LGBTQ. Period. No homosexuality&amp;rdquo; followed by blatant transmisia.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230819214035/https://yggdrasil.social/users/Ricotta&#34;&gt;Profile for &amp;ldquo;Ricotta&amp;rdquo;&lt;/a&gt;, the current most active user, has a swastika in their display name and a bio that includes &amp;ldquo;National Socialist&amp;rdquo; and &amp;ldquo;TERF&amp;rdquo;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.19-214624/https://yggdrasil.social/notice/AXQJkwOuwrASMJo74C&#34;&gt;Blatant racism from another user&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;zhub&#34; tabindex=&#34;-1&#34;&gt;zhub.link&lt;/dt&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.05.11-025205/https://zhub.link/@Revertron/112354798424416207&#34;&gt;strolling into mentions of trans lesbians to post queermisia&lt;/a&gt;, later &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.04.29-214406/https://zhub.link/@Revertron/112354849124040026&#34;&gt;doubling down on it&lt;/a&gt;, describing transness as &amp;ldquo;ugly, illogical&amp;rdquo;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.09.21-085824/https://zhub.link/@Revertron/110904424139458352&#34;&gt;An earlier example&lt;/a&gt; claiming to be oppressed for being labelled homomisic for holding homomisic beliefs.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.12.08-083222/https://zhub.link/@Revertron/111542203459128334&#34;&gt;posts Islamomisic pedojacketing&lt;/a&gt;.&lt;/dd&gt;
&lt;/dl&gt;


&lt;h3 id=&#34;tier-0-entries-excluding-fedinuke&#34;&gt;Tier-0 entries, excluding FediNuke&lt;/h3&gt;
&lt;p&gt;This section is very unfinished. Receipt criteria and threshold is weaker than FediNuke. I encourage most admins to scroll through this list and decide what is or is not acceptable for their instance.&lt;/p&gt;
 &lt;dl&gt;
&lt;dt id=&#34;absolutely-proprietary&#34; tabindex=&#34;-1&#34;&gt;absolutelyproprietary.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240729105559/https://pl.absolutelyproprietary.org/notice/AkPIQLhAvEiPiKBoZM&#34;&gt;Admin self-intro is a racial slur&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/wip/bkCyc&#34;&gt;Posts a series of racial caricatures with slurs in this thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.is/2024.07.29-110355/https://pl.absolutelyproprietary.org/users/pwm&#34;&gt;alt for pwm of crlf.ninja&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;#crlf&#34;&gt;See crlf.ninja FediNuke entry&lt;/a&gt;, featuring pwm.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/CJsIH&#34;&gt;alt for pernia of cum.salon&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;#cumcamp&#34;&gt;See cum.salon FediNuke entry&lt;/a&gt;, featuring pernia.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.10.06-035312/https://pl.absolutelyproprietary.org/notice/AmP0lDp0qntuJfOEzI&#34;&gt;Another user spams BlackMastodon and MutualAid with racial slurs&lt;/a&gt;&lt;/dd&gt;
&lt;dt id=&#34;baraag&#34; tabindex=&#34;-1&#34;&gt;baraag.net&lt;/dt&gt;
&lt;dd&gt;Very well-known lolicon-friendly instance that &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.05-203258/https://baraag.net/@satori/110837928178354824&#34;&gt;recently cleaned up its act enough to re-federate with misskey.io&lt;/a&gt;, but still focuses on lolisho artwork and may therefore pose a legal risk, depending on your jurisdiction. Consider blocking media if you wish to federate.&lt;/dd&gt;
&lt;dt id=&#34;berserker&#34; tabindex=&#34;-1&#34;&gt;berserker.town&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730180929/https://berserker.town/@mayonesa/107949925239774313&#34;&gt;Refuses to moderate hate speech&lt;/a&gt; (the post in question has received reports, but &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730185902/https://berserker.town/@thor/110731212646060568&#34;&gt;the admin tends to dig his heels in&lt;/a&gt; when it comes to this stuff). &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730181711/https://berserker.town/about&#34;&gt;About page&lt;/a&gt; doesn&amp;rsquo;t ban such content.&lt;/dd&gt;
&lt;dd&gt;Permissive policies have made space for &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.10-192342/https://berserker.town/@mayonesa/110730803970638239&#34;&gt;anti-diversity eugenics dogwhistles&lt;/a&gt; evolving into &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810192310/https://berserker.town/@mayonesa/110667720613227224&#34;&gt;xenomisic eugenics&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;federated-fun&#34; tabindex=&#34;-1&#34;&gt;federated.fun OR wikileaks2.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731162711/https://federated.fun/notice/AX46KDxhSkSNkxbSvw&#34;&gt;Blatant transmisia from admin&lt;/a&gt;. Admin profile &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805061250/https://ryona.agency/notice/AYMq4VFzPr2yEcvG3k&#34;&gt;pinned an extremely transmisic post&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810182335/https://misinformation.wikileaks2.org/notice/AYVR3y1faCJhhpwhjk&#34;&gt;switched to running misinformation.wikileaks2.org instead&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231127113147/https://misinformation.wikileaks2.org/notice/AcDQadrG6c4NC98azQ&#34;&gt;continues posting queermisia on the new instance&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;firedragonstudios&#34; tabindex=&#34;-1&#34;&gt;firedragonstudios.com&lt;/dt&gt;
&lt;dd&gt;Currently runs an instance on the &amp;ldquo;pleroma&amp;rdquo; subdomain.&lt;/dd&gt;
&lt;dd&gt;Used to run &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20221001084127/https://freespeech.firedragonstudios.com/@Siedge/with_replies&#34;&gt;a freeze-peach instance under the &amp;ldquo;freespeech&amp;rdquo; subdomain&lt;/a&gt;, allowing &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20221126183927/https://freespeech.firedragonstudios.com/@patriotpast?max_id=105583438413728295&#34;&gt;far-right linkspam&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20220118052456/https://freespeech.firedragonstudios.com/@PhoenixRising/107370066152809226&#34;&gt;anti-vax&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20220621231710/https://freespeech.firedragonstudios.com/users/orangesec_0/statuses/102136233427211000&#34;&gt;anti-woke users&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;Got widely blocked as a result before switching domains. Current &amp;ldquo;pleroma&amp;rdquo; subdomain seems inactive but still allows registration.&lt;/dd&gt;
&lt;dt id=&#34;freesoftwareextremist&#34; tabindex=&#34;-1&#34;&gt;freesoftwareextremist.com&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802162551/https://freesoftwareextremist.com/notice/AYBwS5rDjFaDyIqKtU&#34;&gt;Ableism and antisemitism from local user &amp;ldquo;dookie&amp;rdquo;&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802164139/https://freesoftwareextremist.com/notice/AYItcRuj1hvuTKLhmy&#34;&gt;ableist sui-bait&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802233803/https://freesoftwareextremist.com/notice/AY7nGBF4CsuYydOyxM&#34;&gt;ableism and queermisia&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802231531/https://freesoftwareextremist.com/notice/ATzjhzI7r5Y8Cv1DW4&#34;&gt;often uses anti-Chinese racial slurs&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802231652/https://freesoftwareextremist.com/notice/AY1b8vq2iKh4mIiNcm&#34;&gt;more usage&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.02-232207/https://freesoftwareextremist.com/notice/ARbAeXyGwquJKoxFPk&#34;&gt;other anti-asian slurs&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Instance has fully open registration.&lt;/dd&gt;
&lt;dt id=&#34;ftl&#34; tabindex=&#34;-1&#34;&gt;freetalklive.com&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230802051117/https://social.freetalklive.com/about&#34;&gt;Instance &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; self-identifies as unmoderated, except for spam. Connected to the libertarian Free Talk Live show.&lt;/dd&gt;
&lt;dt id=&#34;kawa-kun&#34; tabindex=&#34;-1&#34;&gt;kawa-kun.net&lt;/dt&gt;
&lt;dd&gt;Instance &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731050219/https://bbs.kawa-kun.com/about&#34;&gt;rejects deletes&lt;/a&gt;. (unfinished entry)&lt;/dd&gt;
&lt;dt id=&#34;kompost&#34; tabindex=&#34;-1&#34;&gt;kompost.cz&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/cWEbG&#34;&gt;Racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804231946/https://kompost.cz/@fuxoft/110656548914018074&#34;&gt;more racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230804232125/https://kompost.cz/@fuxoft/110321506728744090&#34;&gt;transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/Nmop2&#34;&gt;queermisia&lt;/a&gt;. All from admin.&lt;/dd&gt;
&lt;dt id=&#34;krackhouse&#34; tabindex=&#34;-1&#34;&gt;krackhou.se&lt;/dt&gt;
&lt;dd&gt;Admin makes &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231119231756/https://guns.krackhou.se/@trashblaster/statuses/01H9R7ZFR5GMGBC35NVT0HB642&#34;&gt;a blatantly racist TND post&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231119231725/https://guns.krackhou.se/@trashblaster/statuses/01H7QST57SQSB71VP52SW1H65B&#34;&gt;a second such post&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231120000253/https://guns.krackhou.se/@trashblaster/statuses/01HC2SQ8F4WQZ4N1R6C8P3N9K9&#34;&gt;More racial slurs&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;maladaptive-art&#34; tabindex=&#34;-1&#34;&gt;maladaptive.art&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230927221541/https://ap.maladaptive.art/notice/Aa4MbafnEqYugwYMca&#34;&gt;Blatant racism in a transmisic sui-bait thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Same user &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230927225431/https://ap.maladaptive.art/@opal/posts/AZM01RTPDcsHmrse24&#34;&gt;posting blatant transmisia&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230927224155/https://ap.maladaptive.art/notice/Aa4Mj9DfC7jTrW01OC&#34;&gt;misgendering in a transmisic thread&lt;/a&gt;, and &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231022044401/https://ap.maladaptive.art/notice/AaiyV5x86yTyG2OBrU&#34;&gt;antisemitism&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;novoa&#34; tabindex=&#34;-1&#34;&gt;novoa.nagoya&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.11.22-140629/https://novoa.nagoya/notes/9m4x4tzf1m&#34;&gt;Antisemitism from admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;occultist-space&#34; tabindex=&#34;-1&#34;&gt;occultist.space OR enjoyer.network&lt;/dt&gt;
&lt;dd&gt;Run by the same admin as the.usualsuspects.lol (FediNuke). Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230705053714/https://the.usualsuspects.lol/notice/AXKIqzKiWFFDNryNM0&#34;&gt;announced the.usualsuspects.lol from the.occultist.space&lt;/a&gt;. See &lt;a rel=&#34;nofollow&#34; href=&#34;https://pleroma.envs.net/notice/AY6ROdOne8F2oBGjtA&#34;&gt;confirmation that the enjoyer.network admin is the same&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;peister&#34; tabindex=&#34;-1&#34;&gt;peister.org&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240607052542/https://peister.org/notice/AgnDvTdu9Eu0omQusS&#34;&gt;Admin pinned post&lt;/a&gt; is blatant gender-critical/TERF nonsense. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240802075939/https://peister.org/notice/Ak4XrcOhIutyYtZ0MK&#34;&gt;More TERF posts from admin&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240607052917/https://peister.org/users/quasi&#34;&gt;Several more receipts available on the admin profile&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;spc&#34; tabindex=&#34;-1&#34;&gt;shitposter.club OR shitposter.world&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/J8Bhe&#34;&gt;Blatant transmisia from user &amp;ldquo;noyoushutthefuckupdad&amp;rdquo;&lt;/a&gt;, who&amp;rsquo;s &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230731043635/https://shitposter.club/notice/AXhKBOWHdKeWMCUSxs&#34;&gt;gone on multiple transmisic benders&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/qJPUD&#34;&gt;with admin knowledge&lt;/a&gt;. &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230831030108/https://shitposter.club/notice/AZCc1yv50GaHraJnf6&#34;&gt;More transmisia from other users&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;User &amp;ldquo;billiam&amp;rdquo; has a profile with &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230812014901/https://shitposter.club/users/billiam&#34;&gt;a Confederate battle-flag, antisemitic dog-whistles, and blatant white supremacy in a pinned post&lt;/a&gt;&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/sIgyp&#34;&gt;Hosts user &amp;ldquo;Amerika&amp;rdquo;, an outspoken eugenicist and nationalist&lt;/a&gt;. See receipts for their other account in &lt;a rel=&#34;nofollow&#34; href=&#34;#nas&#34;&gt;the FediNuke entry for noagendasocial.com&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;User &amp;ldquo;Nudhul&amp;rdquo; &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20231103203216/https://clubcyberia.co/notice/AbFYbNOEt3Xa79cDBY&#34;&gt;posts racist spam in the &amp;ldquo;MutualAid&amp;rdquo; hashtag&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &amp;ldquo;Moon&amp;rdquo; &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230730211629/https://shitposter.club/notice/AXsvqZCmdxzMPgQN84&#34;&gt;posts racist bait&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.07.31-054410/https://shitposter.club/notice/AT3JYq3GEFzwrvERs0&#34;&gt;Some more racism from user &amp;ldquo;triodug&amp;rdquo;&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Note that its freeze-peach environment probably won&amp;rsquo;t be changing: &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/r254T&#34;&gt;other users, including the admin, seem fond of it in this thread&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;shitposter.world is the successor to shitposter.club following technical difficulties: &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.04.01-022457/https://shitposter.world/notice/AgQHvGpoVFEjzZvXlI&#34;&gt;background information&lt;/a&gt; and &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2024.04.01-143407/https://shitposter.world/notice/AgPLQomASwKKwMzqSm&#34;&gt;admin confirmation&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240331172752/https://shitposter.world/about&#34;&gt;shitposter.world rejects deletes&lt;/a&gt; with the NoIncomingDeletes MRF policy; &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20240403195604/https://gitgud.io/Zero/pleroma/-/raw/stable/lib/pleroma/web/activity_pub/mrf/no_incoming_deletes.ex&#34;&gt;source code of the MRF policy&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;shota-house&#34; tabindex=&#34;-1&#34;&gt;shota.house OR burger.rodeo&lt;/dt&gt;
&lt;dd&gt;Instance &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.07.19-100816/https://shota.house/about&#34;&gt;self-identifies as a freeze peach haven&lt;/a&gt; that permits unrealistic/2D lolisho; this may be a legal risk, depending on your jurisdiction.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805192932/https://shitposter.club/notice/AWUxNv5hDmQJygRNdg&#34;&gt;Staff defends permitting bigotry while dismissing concerns about hate-speech&lt;/a&gt;. With that context, reporting won&amp;rsquo;t address problems like &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805201903/https://clubcyberia.co/notice/AYPLQckGRDb9Dm2gU4&#34;&gt;racist Black fetishism&lt;/a&gt; from one user.&lt;/dd&gt;
&lt;dd&gt;Harassment risk seems low, however, and admins claim that the instance will moderate harassment but not &amp;ldquo;opinion&amp;rdquo;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230805203903/https://pl.kitsunemimi.club/notice/AWO4XxahVkogIxdvMG&#34;&gt;lemmy.burger.rodeo is run by the same staff&lt;/a&gt; and has the same policies.&lt;/dd&gt;
&lt;dt id=&#34;outrnat&#34; tabindex=&#34;-1&#34;&gt;soc0.outrnat.nl&lt;/dt&gt;
&lt;dd&gt;Alleging &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152247/https://outerkosm.us/notes/9e9oqn5357&#34;&gt;reverse-racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Appears to be &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-052017/https://soc.outrnat.nl/notes/9gk8lk7of10cdo9l&#34;&gt;the former admin of springbo.cc&lt;/a&gt;, with a self-professed fascist.&lt;/dd&gt;
&lt;dd&gt;Admin was &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.08.03-191608/https://akko.disqordia.space/notice/AYD8SJUeraaSZI8OXY&#34;&gt;a member of Prometheus Information Systems&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Admin &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152421/https://outerkosm.us/notes/9d7pl7vzvq&#34;&gt;encourages spamming hashtags&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152405/https://outerkosm.us/notes/9d5wudn8rj&#34;&gt;more spam encouragement&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152333/https://outerkosm.us/notes/9dg381vtpy&#34;&gt;defending RMS&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152304/https://outerkosm.us/notes/9d8u8wml55&#34;&gt;the &amp;ldquo;millions must die&amp;rdquo; dogwhistle&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152253/https://outerkosm.us/notes/9d7mgkbjpp&#34;&gt;&amp;ldquo;they&amp;rsquo;re not sending their best&amp;rdquo;&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.06.29-152247/https://outerkosm.us/notes/9d68zgq9lo&#34;&gt;retaliatory CSEM accusations&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;someotherguy&#34; tabindex=&#34;-1&#34;&gt;someotherguy.xyz&lt;/dt&gt;
&lt;dd&gt;Xenomisic &lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.today/2023.12.25-063556/https://pleroma.someotherguy.xyz/notice/Ad7t2XHnqOn3Rw3paK&#34;&gt;&amp;ldquo;build the wall&amp;rdquo; admin&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://ghostarchive.org/archive/1S0Lc?wr=false&#34;&gt;&amp;ldquo;Family values&amp;rdquo; queermisic pedojacketing&lt;/a&gt;.&lt;/dd&gt;
&lt;dt id=&#34;starnix&#34; tabindex=&#34;-1&#34;&gt;starnix.network&lt;/dt&gt;
&lt;dd&gt;Note: there are multiple Fediverse servers on different subdomains, such as &amp;ldquo;pl&amp;rdquo; and &amp;ldquo;mstdn.&amp;rdquo;&lt;/dd&gt;
&lt;dd&gt;Staff includes &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230808200151/https://pl.starnix.network/users/dc&#34;&gt;the admin of annihilation.social and dembased.xyz&lt;/a&gt; (FediNuke).&lt;/dd&gt;
&lt;dt id=&#34;whinge&#34; tabindex=&#34;-1&#34;&gt;whinge.town OR whinge.house&lt;/dt&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://archive.ph/2023.08.06-220550/https://whinge.town/notice/AYRc8jFNLiVczKvKr2#selection-8031.56-8031.62&#34;&gt;Racism from staff&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806215920/https://whinge.town/notice/AYRgdl4uzRV9Sh5GOe&#34;&gt;more racism&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230810043814/https://whinge.town/notice/AYWeC172YMlUxsWJe4&#34;&gt;even more racism&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806223813/https://whinge.town/notice/AXq0Y0n2HDzVWsmOMi&#34;&gt;Ableist misogyny&lt;/a&gt;.&lt;/dd&gt;
&lt;dd&gt;Both instances were set up by the same user (&lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806224027/https://whinge.house/notice/ARzsikv2kOK3V5JaWO&#34;&gt;confirmation 1&lt;/a&gt;, &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230806224027/https://freespeechextremist.com/notice/ARzRYo4L2sPkJv1E2a&#34;&gt;confirmation 2&lt;/a&gt;), who mains on the former.&lt;/dd&gt;
&lt;dt id=&#34;wideboys&#34; tabindex=&#34;-1&#34;&gt;wideboys.org&lt;/dt&gt;
&lt;dd&gt;There used to be an instance on the &amp;ldquo;social&amp;rdquo; subdomain, but it shut down. However, there is still a WriteFreely instance on the &amp;ldquo;blog&amp;rdquo; subdomain. The instance on the &amp;ldquo;social&amp;rdquo; subdomain has been mostly superseded by beefyboys.win.&lt;/dd&gt;
&lt;dd&gt;On the root domain is &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230827195937/https://wideboys.org/BEEFYBOYS.WIN&#34;&gt;a wiki describing how this domain is affiliated with beefyboys.win&lt;/a&gt;. The &lt;a rel=&#34;nofollow&#34; href=&#34;https://web.archive.org/web/20230827200822/https://beefyboys.win/about&#34;&gt;beefyboys.win &amp;ldquo;about&amp;rdquo; page&lt;/a&gt; confirms this.&lt;/dd&gt;
&lt;dd&gt;Since beefyboys.win is on FediNuke and wideboys.org is part of the same network with staff and member overlap, and wideboys.org still federates on the &amp;ldquo;blog&amp;rdquo; subdomain, it&amp;rsquo;s on the list too. But since it only federates via WriteFreely at the time of writing, it looks like a smaller harassment vector so it&amp;rsquo;s demoted to my tier-0 list.&lt;/dd&gt;
&lt;/dl&gt;


&lt;/details&gt;
&lt;h2 id=&#34;future&#34;&gt;Future&lt;/h2&gt;
&lt;p&gt;The biggest complaint I&amp;rsquo;ve heard is the lack of reasons and receipts. I&amp;rsquo;m working on adding them to this page.&lt;/p&gt;
&lt;p&gt;I like the idea of a separation between receipt-tracking projects and blocklist-generating projects. Reasons in a blocklist tend to invite retaliatory harassment in an effort to make admins hide their blocklists, often in the form of (very dubious) legal threats (defamation and privacy regulations have come up).&lt;/p&gt;
&lt;p&gt;I also hope to see more tier-0 lists crop up. Any instance should be able to make a tier-0 list by sub-setting its own blocklist. When that happens, &amp;ldquo;Seirdy&amp;rsquo;s Tier-0 list&amp;rdquo; will hopefully lose whatever authority it has.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Sui-bait is short for suicide-bait.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I did not consider dox attempts against certain neo-Nazis a reason to block.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;A &amp;ldquo;contact stance&amp;rdquo; refers to beliefs around whether it&amp;rsquo;s okay for adults to have sexual relations with minors when a significant age-gap exists. Pro-contact means support for such relations. I consider this support for &lt;abbr&gt;CSA&lt;/abbr&gt;. Regardless of contact stances: I generally agree with blocking instances that allow lolicon, shotacon, sexualized babyfur, etc. but FediNuke is for the most extreme cases of every category.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>The limited utility of the phrase “GNU/Linux”</title>
      <link>https://envs.net/~seirdy/posts/2022/12/09/limited-utility-gnu-linux/</link>
      <pubDate>Fri, 09 Dec 2022 21:48:49 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/12/09/limited-utility-gnu-linux/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/12/09/limited-utility-gnu-linux/">&lt;p&gt;The standard fossbro interjection goes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I&amp;rsquo;d just like to interject for a moment. What you&amp;rsquo;re referring to as Linux, is in fact, GNU/Linux, or as I&amp;rsquo;ve recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sensible retorts, such as &amp;ldquo;Nobody asked you&amp;rdquo;, &amp;ldquo;Please leave us alone&amp;rdquo;, and &amp;ldquo;Sir, this is a Wendy&amp;rsquo;s&amp;rdquo; are useless defenses. Nay, the greatest weapon against misguided pedantry is pedantry itself.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s talk about why &lt;em&gt;not&lt;/em&gt; to use the term &amp;ldquo;GNU/Linux&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;GNU/Linux&amp;rdquo; is not a useful term to describe a category of operating systems. The phrase distinguishes Linux distributions primarily by the presence of GNU software, which is seldom the most meaningful or practical distinction worth making.&lt;/p&gt;
&lt;p&gt;To illustrate the limited utility of &amp;ldquo;GNU/Linux&amp;rdquo; we can study seven Linux distributions, some of which are GNU/Linux:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Fedora CoreOS&lt;/dt&gt;
&lt;dd&gt;A server-oriented distribution intended for containerized workloads. Contains a Linux kernel, GNU libc, GNU coreutils, and the Systemd management suite.&lt;/dd&gt;
&lt;dt&gt;Fedora Workstation&lt;/dt&gt;
&lt;dd&gt;A distribution of the Linux kernel, GNU libc, GNU coreutils, and the Systemd management suite&lt;/dd&gt;
&lt;dt&gt;Gentoo&lt;/dt&gt;
&lt;dd&gt;A distribution of the Linux kernel, GNU libc, GNU coreutils, and the OpenRC init system&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;dt&gt;Alpine&lt;/dt&gt;
&lt;dd&gt;A distribution of the Linux kernel, musl libc, Busybox coreutils, and the OpenRC init system&lt;/dd&gt;
&lt;dt&gt;Void Linux, musl edition&lt;/dt&gt;
&lt;dd&gt;A distribution of the Linux kernel, musl libc, some GNU coreutils, and the Runit init system&lt;/dd&gt;
&lt;dt&gt;ChromeOS&lt;/dt&gt;
&lt;dd&gt;A distribution of the Linux kernel, GNU libc, and a UNIX-like userland abstracted away by default. This is the most popular desktop GNU/Linux distribution, to my knowledge.&lt;/dd&gt;
&lt;dt&gt;Qubes OS&lt;/dt&gt;
&lt;dd&gt;A distribution that uses the Linux kernel but is meant to merely host VMs containing their own OSes&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The phrase &amp;ldquo;GNU/Linux&amp;rdquo; includes all of these distributions except Alpine, and possibly except Void-musl. I argue that drawing this particular line in the sand is hardly ever useful. The right line to draw depends on context.&lt;/p&gt;
&lt;h2 id=&#34;user-experience&#34;&gt;User experience&lt;/h2&gt;
&lt;p&gt;The phrase &amp;ldquo;GNU/Linux&amp;rdquo; doesn&amp;rsquo;t meaningfully describe a Linux distribution&amp;rsquo;s user experience.&lt;/p&gt;
&lt;p&gt;When someone says they use &amp;ldquo;Linux on the desktop&amp;rdquo;, I assume they&amp;rsquo;re referring to a category of OSes that includes all the listed Linux distributions except Fedora CoreOS, ChromeOS, and perhaps Qubes OS. One of the included distributions, Alpine, doesn&amp;rsquo;t ship any GNU software by default. Yet it feels closer to Fedora (a GNU/Linux distribution) than ChromeOS or Qubes OS. The latter two aren&amp;rsquo;t used like traditional &amp;ldquo;*nix&amp;rdquo; systems.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;UNIX-Like&amp;rdquo; or &amp;ldquo;POSIX&amp;rdquo; at least convey the UNIX-like experience and ecosystem of an OS. A &amp;ldquo;Systemd distribution&amp;rdquo; would also be a useful term to describe the experience of configuring and administrating an OS.&lt;/p&gt;
&lt;h2 id=&#34;operating-system-design&#34;&gt;Operating system design&lt;/h2&gt;
&lt;p&gt;The phrase &amp;ldquo;GNU/Linux&amp;rdquo; doesn&amp;rsquo;t meaningfully describe a Linux distribution&amp;rsquo;s high-level design.&lt;/p&gt;
&lt;p&gt;GNU coreutils and glibc both have alternatives that should be nearly equivalent. The use of GNU libraries and coreutils typically doesn&amp;rsquo;t change the design an OS nearly as much as the presence of, say, Systemd. In fact, I would categorize software like GNOME or PulseAudio as targeting &amp;ldquo;Systemd/Linux&amp;rdquo; rather than GNU/Linux: non-Systemd distributions must patch them to run without Systemd. &amp;ldquo;Systemd distribution&amp;rdquo; or &amp;ldquo;Non-Systemd Linux&amp;rdquo; are more useful terms.&lt;/p&gt;
&lt;p&gt;Distinguishing Fedora and Alpine by the use of Systemd versus OpenRC makes far more sense than distinguishing them by their C libraries.&lt;/p&gt;
&lt;p&gt;NixOS and GuixSD feel similar due to their functional package management, not because of their coreutils or C libraries. If NixOS switched to musl and Busybox, I would still feel comfortable putting it in the same category as GuixSD. &amp;ldquo;Functionally packaged distribution&amp;rdquo; would be a more useful term to refer to this pair.&lt;/p&gt;
&lt;h2 id=&#34;targeting-an-os&#34;&gt;Targeting an OS&lt;/h2&gt;
&lt;p&gt;The phrase &amp;ldquo;GNU/Linux&amp;rdquo; is somewhat meaningful when describing a compilation target; however, &amp;ldquo;target triplets&amp;rdquo; are generally more useful.&lt;/p&gt;
&lt;p&gt;Ideally, programs should support linking against different libraries conforming to the same standards. A single program should build for either glibc or musl (and either libstdc++ or libc++ when it uses C++). If I make a GTK or Qt program, I can expect it to run on all the listed OSes except ChromeOS. Alpine and Fedora Workstation are part of more-or-less the same ecosystem, and should share a category.&lt;/p&gt;
&lt;p&gt;This ideal isn&amp;rsquo;t always our reality. Complex software, such as browsers and Systemd, typically requires significant patching to run with musl. Patching fast-moving and complex software like Firefox or Chromium is difficult; patched versions often lag behind official releases. I find it fair to categorize such software as specifically targeting GNU/Linux.&lt;/p&gt;
&lt;p&gt;Categorizing a target as &amp;ldquo;GNU/Linux&amp;rdquo; makes sense when running a pre-compiled binary dynamically linked against glibc (and possibly libstdc++). This is especially relevant for proprietary software shipped exclusively in binary form. Proprietary software tends to be above a certain threshold of complexity; otherwise, it&amp;rsquo;d be trivial to re-implement. Above that complexity threshold, C and C++ libraries probably aren&amp;rsquo;t the only relevant dynamic libraries: the software will likely require system graphics (e.g. libwayland), cryptography (e.g. OpenSSL), and messaging (e.g. libdbus) libraries.&lt;/p&gt;
&lt;h3 id=&#34;target-triplets&#34;&gt;Target triplets&lt;/h3&gt;
&lt;p&gt;When specifying a Linux compilation target, we hardly ever see the term &amp;ldquo;GNU/Linux&amp;rdquo;. Instead, most people use a &lt;dfn&gt;target triplet&lt;/dfn&gt; that specifies the target CPU architecture, kernel, and userland. &amp;ldquo;x86_64-linux-gnu&amp;rdquo; and &amp;ldquo;aarch64-linux-musl&amp;rdquo; are two examples.&lt;/p&gt;
&lt;p&gt;Since the Linux kernel has a stable ABI, it&amp;rsquo;s common to ship binaries statically-linked, with no system libc dependencies. In these situations, pre-compiled Linux binaries may simply drop the last part of a target triple; the two examples would become &amp;ldquo;x86_64-linux&amp;rdquo; and &amp;ldquo;aarch64-linux&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;unclear-meaning&#34;&gt;Unclear meaning&lt;/h2&gt;
&lt;p&gt;The difference between &amp;ldquo;GNU/Linux&amp;rdquo; and &amp;ldquo;Non-GNU/Linux&amp;rdquo; is unclear; this confusion calls into question the value of the term &amp;ldquo;GNU/Linux&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;GuixSD is an OS developed by the GNU project. It uses the GNU coreutils, GNU libc, GNU Shepherd init system, GNU Guile extension language, and GNU Linux-Libre kernel.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; It seems fair to include it in the category of &amp;ldquo;GNU/Linux&amp;rdquo; distributions.&lt;/p&gt;
&lt;p&gt;In contrast: Void Linux&amp;rsquo;s musl edition uses some GNU coreutils. Its init system (Runit), shell (the Almquist Shell), and libc (musl) are not GNU software. Would it make more sense to refer to this distribution as GNU/Linux or musl/Linux? How useful is the distinction?&lt;/p&gt;
&lt;p&gt;&amp;ldquo;GNU&amp;rdquo; alone seems to imply both GNU coreutils and glibc; it doesn&amp;rsquo;t seem to account for the presence of GNU coreutils and the absence of glibc, or vice versa.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The phrase &amp;ldquo;GNU/Linux&amp;rdquo; includes Fedora Workstation, Fedora CoreOS, Gentoo, ChromeOS, and Qubes OS. It&amp;rsquo;s unclear whether it includes Void&amp;rsquo;s musl edition, and it excludes Alpine Linux.&lt;/p&gt;
&lt;p&gt;Running or compiling a dynamically-linked binary is the only situation warranting such a distinction; this is especially important when distributing pre-compiled software. Beyond that scenario, &amp;ldquo;GNU/Linux&amp;rdquo; implies little about the desktop user experience, system administration experience, OS design decisions, or even how much GNU software is present on an OS.&lt;/p&gt;
&lt;p&gt;I would much rather see adoption of the following phrases:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;freedesktop distribution&lt;/dt&gt;
&lt;dd&gt;Refers to the category of UNIX-like desktop-oriented OSes using the software ecosystem that includes GTK, Qt, the AT-SPI accessibility APIs, and the most important freedesktop.org standards. &amp;ldquo;freedesktop Linux distribution&amp;rdquo; could narrow this down to just those with the Linux kernel.&lt;/dd&gt;
&lt;dt&gt;Systemd distribution OR non-Systemd Linux&lt;/dt&gt;
&lt;dd&gt;Refers to the category of Linux distributions that offer a similar configuration and administration experience&lt;/dd&gt;
&lt;dt&gt;POSIX OR UNIX-like&lt;/dt&gt;
&lt;dd&gt;Includes most Linux distributions, the BSDs, Solaris, and others to describe common standards between operating systems&amp;rsquo; low-level design.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;I won&amp;rsquo;t insist on this terminology; I have better things to be pedantic about. I merely wrote this article so I could share it whenever &lt;a href=&#34;https://en.wikipedia.org/wiki/GNU/Linux_naming_controversy&#34;&gt;the GNU/Linux naming controversy&lt;/a&gt; comes up.&lt;/p&gt;
&lt;p&gt;If I shared this article with you after you attempted to incorrect someone&amp;rsquo;s terminology, I&amp;rsquo;d like to leave you with one last copypasta:&lt;/p&gt;
&lt;figure id=&#34;womansplain&#34; tabindex=&#34;-1&#34;&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;I use Linux as my operating system,&amp;rdquo; I state proudly to the unkempt, bearded man. He swivels around in his desk chair with a devilish gleam in his eyes, ready to mansplain with extreme precision. &amp;ldquo;Actually,&amp;rdquo; he says with a grin, &amp;ldquo;Linux is just the kernel. You use GNU+Linux.&amp;rdquo; I don&amp;rsquo;t miss a beat and reply with a smirk, &amp;ldquo;I use Alpine, a distro that doesn&amp;rsquo;t include the GNU coreutils, or any other GNU code. It&amp;rsquo;s Linux, but it&amp;rsquo;s not GNU+Linux.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The smile quickly drops from the man&amp;rsquo;s face. His body begins convulsing and he foams at the mouth as he drop to the floor with a sickly thud. As he writhes around he screams &amp;ldquo;I-IT WAS COMPILED WITH GCC! THAT MEANS IT&amp;rsquo;S STILL GNU!&amp;rdquo; Coolly, I reply: &amp;ldquo;If Windows was compiled with GCC, would that make it GNU?&amp;rdquo; I interrupt his response with &amp;ldquo;And work is being made on the kernel to make it more compiler-agnostic. Even if you were correct, you won&amp;rsquo;t be for long.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;With a sickly wheeze, the last of the man&amp;rsquo;s life is ejected from his body. He lies on the floor, cold and limp. I&amp;rsquo;ve womansplained him to death.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Unknown&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;If you remain unconvinced: that&amp;rsquo;s okay. In the end, what really matters is that I managed to distract you with an unnecessarily-long article, giving me enough time to wrap up the discussion you interrupted.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;There exist several overlays and configurations to use Gentoo with musl, Busybox, different init systems, and even Clang. I&amp;rsquo;m only describing default, mainstream setups.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I imagine most deployments of GuixSD swap out the default Linux-libre kernel with a mainline version, but I lack the evidence to back this claim up.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Stylometric fingerprinting redux</title>
      <link>https://envs.net/~seirdy/posts/2022/07/09/stylometric-fingerprinting-redux/</link>
      <pubDate>Sun, 10 Jul 2022 04:49:06 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/07/09/stylometric-fingerprinting-redux/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/07/09/stylometric-fingerprinting-redux/">&lt;p role=&#34;note&#34;&gt;
This is an expanded version of a microblog entry: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;../../../../../notes/2022/06/24/stylometric-fingerprinting-resistance/&#34;&gt;Stylometric fingerprinting resistance&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. It contains everything in that entry and more.
I am open to feedback, especially from anybody with a more thorough background in the subject; &lt;a href=&#34;https://envs.net/~seirdy/~seirdy/about/&#34;&gt;here’s my contact information&lt;/a&gt;.
&lt;/p&gt;
&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p&gt;Following a recent landmark &lt;abbr title=&#34;Supreme Court of the United States&#34;&gt;SCOTUS&lt;/abbr&gt; ruling, many have been trying to publish resources to help people find reproductive healthcare. They often wish to publish anonymously, to avoid being harassed or doxxed by overzealous religious fundamentalists. Some people asked me for help.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s no shortage of guides on how to stay anonymous online. I recommend using the Tor Browser in a disposable Whonix VM. &lt;a href=&#34;https://www.whonix.org/wiki/Surfing_Posting_Blogging&#34;&gt;The Whonix Wiki has a good guide to anonymous publishing&lt;/a&gt;. Few guides cover &lt;a href=&#34;https://en.wikipedia.org/wiki/Stylometry&#34;&gt;stylometric fingerprinting&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;dfn&gt;Stylometric fingerprinting&lt;/dfn&gt; analyzes unique writing style (i.e., it uses &lt;em&gt;stylometry&lt;/em&gt;) to identify the author of a work. It&amp;rsquo;s one of the most common techniques for de-anonymization, used by adversaries ranging from trolls to law enforcement.&lt;/p&gt;
&lt;p&gt;For a &lt;abbr title=&#34;Too Long; Didn&#39;t Read&#34;&gt;TL;DR&lt;/abbr&gt;, skip to &lt;a href=&#34;#conclusion&#34;&gt;the &amp;ldquo;Conclusion&amp;rdquo; section&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;how-stylometric-fingerprinting-works&#34;&gt;How stylometric fingerprinting works&lt;/h2&gt;
&lt;p&gt;To paint with a broad brush, we can divide most stylometric fingerprinting into machine- and human-driven techniques.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Machine-driven techniques&lt;/dt&gt;
&lt;dd&gt;These techniques involve analysis of reading level metrics, unusual words, machine-identifiable grammatical and spelling errors, and statistical analysis of writing style. A great amount of recent research studies statistical analysis of writing style; it&amp;rsquo;s a rapidly-evolving field.&lt;/dd&gt;
&lt;dt&gt;Human-driven techniques&lt;/dt&gt;
&lt;dd&gt;There are some areas in which manual analysis still beats computers. Someone you know may recognize your writing style.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;defense-against-machine-driven-techniques&#34;&gt;Defense against machine-driven techniques&lt;/h2&gt;
&lt;p&gt;Common advice is to use offline machine translation to translate works to and from another language. &lt;a href=&#34;https://www.argosopentech.com/&#34;&gt;Argos Translate&lt;/a&gt; and &lt;a href=&#34;https://marian-nmt.github.io/&#34;&gt;Marian&lt;/a&gt; are two options that come to mind.&lt;/p&gt;
&lt;h3 id=&#34;obfuscation-and-imitation&#34;&gt;Obfuscation and imitation&lt;/h3&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://doi.org/10.1145/2382448.2382450&#34;&gt;Adversarial stylometry: Circumventing authorship recognition to preserve privacy and anonymity&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; shows that machine translation alone isn&amp;rsquo;t nearly as strong a method as manual approaches: obfuscation (hiding your writing style) or imitation (mimicking another author). These approaches have excellent success rates, even among amateur writers. The aforementioned Whonix wiki page lists common stylometric fingerprinting vectors for manual approaches to address.&lt;/p&gt;
&lt;p&gt;Limiting unusual vocabulary and sentence structure make for a good start. Using a comprehensive and highly-opinionated style-guide should also help. &lt;cite&gt;The Economist&lt;/cite&gt; has a good one that was specifically written to make all authors sound the same: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://cdn.static-economist.com/sites/default/files/pdfs/style_guide_12.pdf&#34;&gt;The Economist Style Guide&lt;/a&gt;&lt;/cite&gt;, &lt;span&gt;12th edition&lt;/span&gt; (&lt;span&gt;application/&lt;wbr /&gt;pdf&lt;/span&gt;)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Nearly every respected newspaper has a style guide. Tech companies typically publish or use a style guide for technical writing. I&amp;rsquo;m a fan of Red Hat&amp;rsquo;s style guide: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://stylepedia.net/style/5.1/&#34;&gt;Red Hat Technical Writing Style Guide&lt;/a&gt;&lt;/cite&gt;, &lt;span&gt;Edition 5.1&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Good style guides are long, and learning one is tough. Read a large amount of conforming content to help yourself internalize a guide&amp;rsquo;s rules.&lt;/p&gt;
&lt;h3 id=&#34;reading-levels&#34;&gt;Reading levels&lt;/h3&gt;
&lt;p&gt;The reading difficulty of a piece is a coarse but extremely simple measure. If the anonymous author of a piece writes at a tenth-grade level, their other writings are likely near a tenth-grade level too.&lt;/p&gt;
&lt;p&gt;Check your content&amp;rsquo;s reading level using common readability metrics. The &lt;a href=&#34;https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests&#34;&gt;Flesch-Kincaid Grade Level&lt;/a&gt; is one of the most popular. If you write at a given grade level, publish anonymously at a lower grade level. I recommend using a lower grade level rather than a higher one for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Artificially inflating the reading level generally produces cringeworthy writing.&lt;/li&gt;
&lt;li&gt;Writing at a lower level carries less risk of introducing uncommon fingerprintable words.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;other-tips&#34;&gt;Other tips&lt;/h3&gt;
&lt;p&gt;For any inexperienced writers: opinionated offline grammar checkers such as &lt;a href=&#34;https://github.com/languagetool-org/languagetool&#34;&gt;LanguageTool&lt;/a&gt; and &lt;a href=&#34;https://github.com/redpen-cc/redpen&#34;&gt;RedPen&lt;/a&gt; may supplement a manual approach by normalizing any distinguishing &amp;ldquo;errors&amp;rdquo; in your language. That being said, nothing beats a human editor. Find someone you trust to review your work.&lt;/p&gt;
&lt;p&gt;Here are some resources for further reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.orphanalytics.com/en/method&#34;&gt;How we authenticate a document&lt;/a&gt;&lt;/cite&gt; by &lt;span&gt;OrphAnalytics SA&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://serhack.me/articles/unveiling-anonymous-author-stylometry-techniques/&#34;&gt;Unveiling the Anonymous Author: Stylometry Techniques&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://serhack.me/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;SerHack&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;defense-against-human-driven-techniques&#34;&gt;Defense against human-driven techniques&lt;/h2&gt;
&lt;p&gt;Human-driven techniques were behind the most high-profile successful cases of stylometric fingerprinting by law enforcement. When the Unabomber published his manifesto, his brother recognized some signature phrases in his manifesto and went to the FBI. One of the largest Australian CSA cases involved &lt;a href=&#34;https://www.nowtolove.com.au/news/real-life/the-online-child-sex-abuse-epidemic-9139&#34;&gt;recognizing someone&amp;rsquo;s distinctive greeting of &amp;ldquo;Hiya&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While the research I cited seems to indicate that machine translation is a poor way to thwart machine-driven techniques, I&amp;rsquo;m not convinced that it&amp;rsquo;s useless. Machine translation may be ineffective at thwarting machine-driven stylometric fingerprinting, but it should be able to highlight or remove uniqueness a human could notice. Let&amp;rsquo;s look at some examples.&lt;/p&gt;
&lt;h3 id=&#34;example-unabomber-manifesto&#34;&gt;Example: Unabomber manifesto&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s a sentence from the Unabomber manifesto:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But it is obvious that modern leftist philosophers are not simply &lt;mark&gt;cool-headed logicians&lt;/mark&gt; systematically analyzing the foundations of knowledge.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;David Kaczynski noticed the phrase &amp;ldquo;cool-headed logicians&amp;rdquo; as a potential signature identifying his brother. After further analysis, the author was clear.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;After I read the first few pages, my jaw literally dropped. One particular phrase disturbed me. It said modern philosophers were not “cool-headed logicians.” Ted had once said I was not a “cool-headed logician,” and I had never heard anyone else use that phrase…We had Linda’s childhood friend Susan Swanson, a private investigator, take two of Ted’s letters to a linguistics expert, who analyzed them and found there was an 80 percent chance the same person had written the letters and the manifesto.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://web.archive.org/web/20100316051613/http://blog.timesunion.com/kaczynski/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;David&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Kaczynski&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://people.com/archive/blood-bond-vol-50-no-4/&#34;&gt;Blood Bond&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Let&amp;rsquo;s run it through Argos Open Translate&amp;rsquo;s English-Esperanto filter,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and then translate it back to English:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But it is evident that modern left-wing philosophers are not simply &lt;mark&gt;dehydrated logicians&lt;/mark&gt; systematically analyzing the foundations of knowledge.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;ldquo;Dehydrated logicians&amp;rdquo; obviously isn&amp;rsquo;t the correct term to use. The fact that the translation algorithm mistook &amp;ldquo;cool-headed&amp;rdquo; for &amp;ldquo;dehydrated&amp;rdquo; indicates that &amp;ldquo;cool-headed&amp;rdquo; was an unusual choice of words to use in this context, and therefore a fingerprinting vector. A more common phrase like &amp;ldquo;detached&amp;rdquo; would be safer.&lt;/p&gt;
&lt;h3 id=&#34;extreme-example-mario&#34;&gt;Extreme example: Mario&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s look at another phrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Whoohoo! It&amp;rsquo;s a-me, Mario!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;ldquo;Mario&amp;rdquo; is a common name, but I have a feeling you know that &lt;a href=&#34;https://en.wikipedia.org/wiki/Mario&#34;&gt;this &amp;ldquo;Mario&amp;rdquo; is the Nintendo character&lt;/a&gt;. Running this line through an English-Esperanto and Esperanto-English filter gives us:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Who! It&amp;rsquo;s me, Mary!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Our findings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Whoohoo&amp;rdquo; is uncommon enough to be unrecognized by the translation algorithm. Replace or remove it.&lt;/li&gt;
&lt;li&gt;Saying &amp;ldquo;a-me&amp;rdquo; is less common than saying &amp;ldquo;me&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Mario&amp;rdquo; is less common than &amp;ldquo;Mary&amp;rdquo; in an English-speaking context.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, inflection (e.g., using an exclamation point) can make your writing voice recognizable. Use it with care.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s re-phrase Mario&amp;rsquo;s line to be less identifiable:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey, it&amp;rsquo;s me. Mario.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;rsquo;s a little better.&lt;/p&gt;
&lt;h2 id=&#34;example-my-fingerprint&#34;&gt;Example: my fingerprint&lt;/h2&gt;
&lt;p&gt;I have my share of fingerprintable stylistic and formatting quirks. A non-exhaustive list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Qualifying lists with words like &amp;ldquo;non-exhaustive&amp;rdquo; or &amp;ldquo;incomplete&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Putting punctuation outside quotations or hyperlinks whenever acceptable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using many colons, semicolons and conjunctive adverbs; for example, this sentence uses the latter two.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Obsessively distinguishing between concepts and implementations of those concepts, resulting in a statistically high use of the word &amp;ldquo;implementation&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Introducing some articles with HTML description lists before elaborating on each entry in that list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using soft-hyphens so text can wrap to narrow widths.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;writing-is-a-skill&#34;&gt;Writing is a skill&lt;/h2&gt;
&lt;p&gt;Developing a high-quality writing style is hard. Developing and switching between multiple different styles is even harder. It takes time to master multiple style guides, cultivate a different &amp;ldquo;voice&amp;rdquo; free of your usual idiosyncrasies, and keep your different voices from influencing one another. &amp;ldquo;Getting into character&amp;rdquo; won&amp;rsquo;t happen overnight if you don&amp;rsquo;t have experience.&lt;/p&gt;
&lt;p&gt;Translation tools are &lt;span data-literal=&#34;temporary learning aids&#34;&gt;training-wheels&lt;/span&gt; to help you learn to identify idiosyncrasies. As you get better, you might be able to filter out problematic language without their help.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t feel pressured to start soon! If you want to publish under a truly anonymous pseudonym, you should first hone your craft. Alternatively, find a good editor.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;section role=&#34;doc-conclusion&#34;&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you wish to write anonymously, I recommend the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Analyze your non-anonymous writing, looking for patterns. Write these patterns down. When you review your anonymous publications, refer to your list of identifiable patterns and remove them. Consider asking someone else for help, since your own bias might cause you to overlook some patterns.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Translate your work to and from another language with an offline machine translator. Don&amp;rsquo;t actually publish the translator&amp;rsquo;s output; instead, read the output to identify potentially-fingerprintable language you missed in the previous step.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Correct any grammatical or spelling errors; mistakes you make might be unique.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conform to an opinionated style-guide that you don&amp;rsquo;t normally use in your other writing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If, after doing the prior steps, your anonymous work still has a reading level too similar to your non-anonymous writing: reduce the reading level by choosing simpler words.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;More information on stylometric fingerprinting resistance is on &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://anonymousplanet.org/guide.html#appendix-a4-counteracting-forensic-linguistics&#34;&gt;The Hitchiker&#39;s Guide to Online Anonymity&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Stay safe, everyone.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I didn&amp;rsquo;t pick Esperanto for any particular reason.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I am not the best person for this job, sorry.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>An experiment to test GitHub Copilot&#39;s legality</title>
      <link>https://envs.net/~seirdy/posts/2022/07/01/experiment-copilot-legality/</link>
      <pubDate>Sat, 02 Jul 2022 00:30:45 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/07/01/experiment-copilot-legality/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/07/01/experiment-copilot-legality/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;I am not a lawyer. This post is satirical commentary on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The absurdity of Microsoft and OpenAI&amp;rsquo;s legal justification for GitHub Copilot.&lt;/li&gt;
&lt;li&gt;The oversimplifications people use to argue against GitHub Copilot (I don&amp;rsquo;t like it when people agree with me for the wrong reasons).&lt;/li&gt;
&lt;li&gt;The relationship between capital and legal outcomes.&lt;/li&gt;
&lt;li&gt;How civil cases seem like sporting events where people &amp;ldquo;win&amp;rdquo; or &amp;ldquo;lose&amp;rdquo;, rather than opportunities to improve our understanding of law.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the process, I intentionally misrepresent how the judicial system works: I portray the system the way people like to imagine it works. Please don&amp;rsquo;t make any important legal decisions based on anything I say.&lt;/p&gt;
&lt;p&gt;The only section you should take seriously is &lt;a href=&#34;#context&#34;&gt;&amp;ldquo;Context: the relevant technologies&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;GitHub is enabling copyleft violation &lt;span aria-hidden=&#34;true&#34;&gt;✨&lt;/span&gt;at scale&lt;span aria-hidden=&#34;true&#34;&gt;✨&lt;/span&gt; with Copilot. GitHub Copilot encourages people to make derivative works of source code without complying with the original code&amp;rsquo;s license. This facilitates the creation of permissively-licensed or proprietary derivatives of copyleft code.&lt;/p&gt;
&lt;p&gt;Unfortunately, challenging Microsoft (GitHub&amp;rsquo;s parent company) in court is a bad idea: their legal budget probably ensures their victory, and they likely already have a comprehensive defense planned. How can we determine Copilot&amp;rsquo;s legality on a level playing field? We can create legal precedent that they haven&amp;rsquo;t had a chance to study yet!&lt;/p&gt;
&lt;p&gt;A chat with &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://mwcampbell.us/blog/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Matt&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Campbell&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; about a speech synthesizer gave me a horrible idea. I think I know a way to find out if GitHub Copilot is legal: we could use its legal justification against another software project with a smaller legal budget. Specifically, against a speech synthesizer. The outcome of our actions could set a legal precedent to determine the legality of Copilot.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;context&#34;&gt;Context: the relevant technologies&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s cover the technologies and actors at play &lt;em&gt;before&lt;/em&gt; I start my evil monologue.&lt;/p&gt;
&lt;h3 id=&#34;exhibit-a-github-copilot&#34;&gt;Exhibit A: GitHub Copilot&lt;/h3&gt;
&lt;p&gt;&lt;dfn&gt;GitHub Copilot&lt;/dfn&gt; is a predictive autocompletion service for writing software. It&amp;rsquo;s powered by &lt;a href=&#34;https://openai.com/blog/openai-codex/&#34;&gt;OpenAI Codex&lt;/a&gt;, a language model based on &lt;a href=&#34;https://en.wikipedia.org/wiki/GPT-3&#34;&gt;GPT-3&lt;/a&gt;. It was trained using the source code of public repositories hosted on GitHub, regardless of their licensing. In response to a Request for Comments from the US Patent and Trademark Office, OpenAI claimed that &amp;ldquo;Artificial Intelligence Innovation&amp;rdquo;, such as code written by GitHub Copilot, should be considered &amp;ldquo;fair use&amp;rdquo;.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Many of the code snippets it suggests are exact copies of source code from various GitHub repositories. For an example, see this tweet: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://web.archive.org/web/20230130102944/https://twitter.com/mitsuhiko/status/1410886329924194309&#34;&gt;I don&#39;t want to say anything but that&#39;s not the right license Mr Copilot.&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://lucumr.pocoo.org/about/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Armin&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Ronacher&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; (here&amp;rsquo;s an &lt;a href=&#34;https://web.archive.org/web/20220701010012/https://nitter.pussthecat.org/mitsuhiko/status/1410886329924194309&#34;&gt;archive link that doesn&amp;rsquo;t require JavaScript&lt;/a&gt;, captured on &lt;time datetime=&#34;2022-07-01T01:00:12+00:00&#34;&gt;2022-07-01&lt;/time&gt;) &lt;span&gt;It contains a screen recording of Copilot suggesting &lt;a href=&#34;https://github.com/id-Software/Quake-III-Arena/blob/dbe4ddb10315479fc00086f08e25d968b4b43c49/code/game/q_math.c#L552&#34;&gt;this Quake code&lt;/a&gt;. When prompted to do so, it obediently fills in a permissive license.&lt;/span&gt;&lt;/span&gt; That permissive license violates &lt;a href=&#34;https://github.com/id-Software/Quake-III-Arena/blob/dbe4ddb10315479fc00086f08e25d968b4b43c49/COPYING.txt&#34;&gt;the Quake code&amp;rsquo;s GPL-2.0 license&lt;/a&gt;. Copilot provides no indication that a license violation is taking place.&lt;/p&gt;
&lt;p&gt;GitHub performed its own research into the matter.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; You can read about it on their blog: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://github.blog/2021-06-30-github-copilot-research-recitation/&#34;&gt;GitHub Copilot research recitation&lt;/a&gt;&lt;/cite&gt;, by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://github.com/wunderalbert&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Albert&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Ziegler&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;. I&amp;rsquo;m not convinced that it accounts for the fact that suggested code might have mechanical alterations to match surrounding text, while still remaining close enough to trained data to be a license violation.&lt;/p&gt;
&lt;h3 id=&#34;exhibit-b-the-eloquence-speech-synthesizer&#34;&gt;Exhibit B: The Eloquence speech synthesizer&lt;/h3&gt;
&lt;p&gt;I recently had a chat with Matt on IRC about screen readers and different types of speech synthesizers. I mentioned that while I do like some variety, I always find myself returning to the underrated robotic voice of &lt;a href=&#34;https://github.com/espeak-ng/espeak-ng/&#34;&gt;eSpeak NG&lt;/a&gt;. He shared some of my fondness, and also shared his preference for a similar speech synthesizer called Eloquence.&lt;/p&gt;
&lt;p&gt;Downloads of Eloquence are easy to find (it&amp;rsquo;s even included with the JAWS screen reader), but I struggle to find any &amp;ldquo;official&amp;rdquo; pages about the original Eloquence. Nuance acquired Eloquent Technology, the developer of Eloquence. Microsoft later acquired Nuance.&lt;/p&gt;
&lt;hr /&gt;
&lt;section
	aria-label=&#34;audio, caption, and transcript&#34;
	
	id=&#34;eloquence&#34; tabindex=&#34;-1&#34;&gt;
&lt;h4 id=&#34;eloquence-sample&#34;&gt;&lt;span&gt;Eloquence sample audio&lt;/span&gt;&lt;/h4&gt;
&lt;figure&gt;
&lt;audio
	controls=&#34;&#34;
	aria-describedby=&#34;transcript-eloquence&#34;
	preload=&#34;auto&#34;&gt;
	&lt;source
		src=&#34;https://envs.net/~seirdy/~seirdy/a/eloquence.1948139139.opus&#34;
		type=&#39;audio/ogg; codecs=&#34;opus&#34;&#39; /&gt;
	&lt;source
		src=&#34;https://envs.net/~seirdy/~seirdy/a/eloquence.2387178485.mp3&#34;
		type=&#34;audio/mpeg&#34; /&gt;
	&lt;p role=&#34;note&#34;&gt;Your browser does not support HTML5 audio.&lt;/p&gt;
	&lt;/audio&gt;
&lt;a
	href=&#34;https://envs.net/~seirdy/~seirdy/a/eloquence.mp3&#34; download=&#34;&#34;
	&gt;Download audio file &lt;samp translate=&#34;no&#34;&gt;eloquence.mp3&lt;/samp&gt;&lt;/a&gt;
&lt;figcaption&gt;
&lt;p&gt;Matt recorded this sample audio clip of Eloquence reading some text. The text is from the introduction of &lt;span
class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;../../../../2020/11/23/website-best-practices/&#34;&gt;Best practices for inclusive textual websites&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;details&gt;
&lt;summary&gt;Toggle audio &lt;span&gt;transcript&lt;/span&gt;&lt;/summary&gt;
&lt;section id=&#34;transcript-eloquence&#34;&gt;
&lt;h5&gt;Audio transcript&lt;/h5&gt;
	&lt;div&gt;
		My primary focus is inclusive design. Specifically, I focus on supporting underrepresented ways to read a page. Not all users load a page in a common web-browser and navigate effortlessly with their eyes and hands. Authors often neglect people who read through accessibility tools, tiny viewports, machine translators, “reading mode” implementations, the Tor network, printouts, hostile networks, and uncommon browsers, to name a few. I list more niches in the conclusion. Compatibility with so many niches sounds far more daunting than it really is: if you only selectively override browser defaults and use plain-old, semantic HTML (POSH), you&amp;rsquo;ve done half of the work already.
&lt;/div&gt;
&lt;/section&gt;
&lt;/details&gt;
&lt;/section&gt;
&lt;hr /&gt;

&lt;p&gt;I like the Eloquence speech synthesizer. It sounds similar to the robotic yet predictable voice of my beloved eSpeak NG, but with improved overall quality. Unfortunately, Eloquence is proprietary.&lt;/p&gt;
&lt;h3 id=&#34;exhibit-c-deep-learning-speech-synthesis&#34;&gt;Exhibit C: Deep learning speech synthesis&lt;/h3&gt;
&lt;p&gt;&lt;dfn&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Deep_learning_speech_synthesis&#34;&gt;Deep learning speech synthesis&lt;/a&gt;&lt;/dfn&gt; is a recent approach to speech synthesizer creation. It involves training a deep neural network on voice samples, and using the trained model to generate speech similar to a real human voice. One synthesizer using deep learning speech synthesis is &lt;a href=&#34;https://github.com/mozilla/TTS&#34;&gt;Mozilla&amp;rsquo;s TTS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Zero-shot approaches could allow a pre-trained model to generate multiple different voices. &lt;a href=&#34;https://doi.org/10.48550/arXiv.2112.02418&#34;&gt;YourTTS&lt;/a&gt; is one such example. This could allow us to synthetically re-create a person&amp;rsquo;s voice more easily.&lt;/p&gt;
&lt;h2 id=&#34;my-horrible-plan&#34;&gt;My horrible plan&lt;/h2&gt;
&lt;p&gt;My horrible plan revolves around going through two different lawsuits to set some judicial precedents; these precedents could improve the odds of succeeding in a lawsuit against Microsoft for Copilot&amp;rsquo;s licensing violations.&lt;/p&gt;
&lt;p&gt;If this succeeds, we have new legal justification that GitHub Copilot is illegal; if it fails, we have still gained a means to legally re-create proprietary software. It&amp;rsquo;s a win-win situation.&lt;/p&gt;
&lt;h3 id=&#34;part-one-set-a-precedent&#34;&gt;Part One: set a precedent&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Train a modern text-to-speech (TTS) engine using the voice a proprietary one made by a company with a small legal budget. Keep the model&amp;rsquo;s internals hidden.&lt;/li&gt;
&lt;li&gt;Then release the final TTS under a permissive license. Remember, we&amp;rsquo;re still keeping the machine-learning model hidden!&lt;/li&gt;
&lt;li&gt;Wait for that company to file suit.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Win or lose the case.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;part-two-use-that-precedent-against-microsofts-nuance&#34;&gt;Part Two: use that precedent against Microsoft&amp;rsquo;s Nuance&lt;/h3&gt;
&lt;p&gt;Our goal here is to get the same legal outcome as the low-stakes &amp;ldquo;trial run&amp;rdquo; of Part One.&lt;/p&gt;
&lt;p&gt;Microsoft owns Nuance. Nuance previously bought Eloquent Technology, the developers of the Eloquence speech synthesizer.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Repeat Part One against Nuance speech synthesizers, including Eloquence. Go to court.&lt;/li&gt;
&lt;li&gt;Have the ruling from Part One cited as legal precedent.&lt;/li&gt;
&lt;li&gt;Achieve the same outcome as Part One, demonstrating that we have indeed set precedent that works against Microsoft&amp;rsquo;s legal department.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;implications-of-the-outcomes&#34;&gt;Implications of the outcomes&lt;/h3&gt;
&lt;p&gt;If we &lt;em&gt;win&lt;/em&gt; both cases: Microsoft has the legal high ground. Making a derivative of a copyrighted work using a machine-learning algorithm allows us to bypass copyright licenses.&lt;/p&gt;
&lt;p&gt;If we &lt;em&gt;lose&lt;/em&gt; both cases: Microsoft does not have the legal high ground. We have good judicial precedent against Microsoft to use when filing suit for Copilot&amp;rsquo;s behavior.&lt;/p&gt;
&lt;p&gt;Either way, it&amp;rsquo;s an absolute win for free software. Taking down Copilot protects copyleft from enabling proprietary derivatives (and by extension, protects software freedom). But if we accidentally win these two low-stakes &amp;ldquo;test&amp;rdquo; cases, we still gain something else: we can liberate huge swaths of proprietary software, starting with speech synthesizers.&lt;/p&gt;
&lt;section role=&#34;doc-conclusion&#34;&gt;
&lt;h2 id=&#34;update-on-satire&#34;&gt;Update: on satire&lt;/h2&gt;
&lt;p&gt;This post isn&amp;rsquo;t &amp;ldquo;satire through-and-through&amp;rdquo; like something from The Onion. Rather, my intent was to make some clear points, but extrapolate them to absurdity to highlight other problems. I don&amp;rsquo;t think I was clear enough when doing this. I&amp;rsquo;m sorry.&lt;/p&gt;
&lt;p&gt;Copilot has been found to suggest significant amounts of code that is dangerously similar to existing works. It does this without disclosing obligations that come with those works&amp;rsquo; licenses. Training a model on copyrighted works may not be wrong in and of itself; however, using that model to generate new works that are not sufficiently distinct from original works is where things get problematic. Copilot&amp;rsquo;s users could apply proprietary licenses to the generated works, defeating the point of copyleft.&lt;/p&gt;
&lt;p&gt;When a tool almost exclusively encourages problematic behavior, the makers of that tool should have put thought into its implications. GitHub and OpenAI have not demonstrated a sufficiently careful approach.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think that &amp;ldquo;going after&amp;rdquo; a smaller player just to manipulate our legal system is a good thing to do. The fact that this idea seems plausible to some of my readers shows how warped our perception of the judicial system is. Even if it&amp;rsquo;s accurate (I doubt it&amp;rsquo;s accurate, but I&amp;rsquo;m not certain), it&amp;rsquo;s sad. Judicial systems incentivise too much predatory behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section role=&#34;doc-errata&#34;&gt;
&lt;h2 id=&#34;corrections&#34;&gt;Corrections&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;Updated on &lt;time&gt;2022-07-02&lt;/time&gt;: &lt;span&gt;It&amp;rsquo;s has come to my attention that Eloquence may or may not still belong to Nuance. Further research is needed. Eloquent Technology was acquired by SpeechWorks in 2000.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;See &lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.uspto.gov/sites/default/files/documents/OpenAI_RFC-84-FR-58141.pdf&#34;&gt;Comment Regarding Request for Comments on Intellectual Property Protection for Artificial Intelligence Innovation&lt;/a&gt;&lt;/cite&gt; (&lt;span&gt;application/pdf&lt;/span&gt;) submitted by &lt;span&gt;&lt;span&gt;OpenAI&lt;/span&gt;&lt;/span&gt; to the &lt;abbr title=&#34;United States Patent and Trademark Office&#34;&gt;USPTO&lt;/abbr&gt;&lt;/span&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I doubt anybody worth their salt would count on a company to hold itself accountable, but at least they tried.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;If the stars align, you could file an anticipatory suit against the company. It&amp;rsquo;s common for &lt;a href=&#34;https://en.wikipedia.org/wiki/Declaratory_judgement&#34;&gt;declaratory judgement&lt;/a&gt; regarding intellectual property rights.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Two types of privacy</title>
      <link>https://envs.net/~seirdy/posts/2022/06/25/two-types-of-privacy/</link>
      <pubDate>Sat, 25 Jun 2022 22:25:14 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/06/25/two-types-of-privacy/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/06/25/two-types-of-privacy/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2 id=&#34;preface&#34;&gt;Preface&lt;/h2&gt;
&lt;p&gt;Threat modelling provides important context to security and privacy advice. Measures necessary to protect against an advanced threat are different from those effective against unsophisticated threats. Moreover, threats don&amp;rsquo;t always fall along a simple one-dimensional axis from &amp;ldquo;simple&amp;rdquo; to &amp;ldquo;advanced&amp;rdquo;. I appreciate seeing communities acknowledge this complexity.&lt;/p&gt;
&lt;p&gt;When qualifying privacy recommendations with context, I think we should go further than describing threat models: we should acknowledge different types of privacy. &amp;ldquo;Privacy&amp;rdquo; means different things to different people. Even a single person may use the word &amp;ldquo;privacy&amp;rdquo; differently depending on their situation. Understanding a user&amp;rsquo;s unique situation(s), &lt;em&gt;including their threat models,&lt;/em&gt; can inform us when we select the best of approach. How do we choose between reducing a footprint&amp;rsquo;s &lt;em&gt;spread&lt;/em&gt; and &lt;em&gt;size?&lt;/em&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#introduction&#34;&gt;Intro­duction&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#tracking-reduction-tr&#34;&gt;Tracking reduction (TR)&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#sample-tr-techniques&#34;&gt;Sample TR techniques&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#attack-surface&#34;&gt;Attack surface&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#tracking-evasion-te&#34;&gt;Tracking evasion (TE)&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#sample-te-techniques&#34;&gt;Sample TE techniques&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#half-measures-are-ineffective&#34;&gt;Half-measures are ineffective&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#conflicts-between-tr-and-te&#34;&gt;Conflicts between TR and TE&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#badness-enumeration-content-blocking&#34;&gt;Badness enumeration: content blocking&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#dnt&#34;&gt;Do Not Track (DNT)&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#exceptions-and-overlap&#34;&gt;Exceptions and overlap&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#how-to-make-privacy-recommendataions&#34;&gt;How to make privacy recommen­dations&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#threat-modelling&#34;&gt;Threat modelling&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#conclusion&#34;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p&gt;I highlight two main approaches to privacy: &amp;ldquo;tracking reduction&amp;rdquo; and &amp;ldquo;tracking evasion&amp;rdquo;.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;dfn&gt;Tracking reduction&lt;/dfn&gt; (&lt;abbr title=&#34;Tracking Reduction&#34;&gt;TR&lt;/abbr&gt;)&lt;/dt&gt;
&lt;dd&gt;TR aims to reduce the amount of data collected about an exposed user. It reduces a footprint&amp;rsquo;s &lt;em&gt;spread&lt;/em&gt; primarily by blocking trackers. Sometimes this can increase the size of a footprint.&lt;/dd&gt;
&lt;dt&gt;&lt;dfn&gt;Tracking evasion&lt;/dfn&gt; (&lt;abbr title=&#34;Tracking Evasion&#34;&gt;TE&lt;/abbr&gt;)&lt;/dt&gt;
&lt;dd&gt;TE reduces the amount of data exposed by a user. Rather than eliminating data collection itself, TE prevents useful data from being made available in the first place. In other words, it reduces a footprint&amp;rsquo;s &lt;em&gt;size.&lt;/em&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;There is gray area between these two extremes, and not every privacy measure falls neatly into one of these two categories. I&amp;rsquo;ll address that later in this article.&lt;/p&gt;
&lt;p role=&#34;note&#34;&gt;Note: this article focuses primarily on Web browsers; however, its concepts can apply to any software capable of tracking users.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get started:&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;tracking-reduction-tr&#34;&gt;Tracking reduction (TR)&lt;/h2&gt;
&lt;p&gt;&lt;abbr title=&#34;Tracking Reduction&#34;&gt;TR&lt;/abbr&gt; is suitable for casual threat models. These techniques typically aim to remove trackers or to block malicious traffic.&lt;/p&gt;
&lt;p&gt;If someone just wants to browse the web with less tracking, they&amp;rsquo;re probably not expecting a &amp;ldquo;nuclear option&amp;rdquo; that removes all their personalization. That user is more likely to be concerned with manipulation by personalized ads, or something vague such as being &amp;ldquo;followed around&amp;rdquo; as they browse websites while signed out.&lt;/p&gt;
&lt;p&gt;These users are likely okay with being identified by a site; several of their accounts are probably linked to the same identity. However, when they log into &amp;ldquo;example.com&amp;rdquo;, they&amp;rsquo;d rather not ping trackers from &amp;ldquo;facebook.com&amp;rdquo; or &amp;ldquo;amazon-adsystem.com&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Of course, data-sharing could happen on the backend. Users may accept that there&amp;rsquo;s little they can do about this beyond reading a privacy policy and filing suit upon violations.&lt;/p&gt;
&lt;p&gt;In other words, TR falls closer to &amp;ldquo;wants&amp;rdquo; on the (somewhat contrived) &amp;ldquo;wants versus needs&amp;rdquo; spectrum. It addresses the gray area between personal preferences and real present threats. Our goal is to reduce tracking where we can, without significantly degrading the user experience.&lt;/p&gt;
&lt;h3 id=&#34;sample-tr-techniques&#34;&gt;Sample TR techniques&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Badness enumeration: content-blocking and firewalls.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sending headers such as &lt;a href=&#34;https://globalprivacycontrol.org/&#34;&gt;Global Privacy Control&lt;/a&gt; or &lt;a href=&#34;#dnt&#34;&gt;Do Not Track.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Opting out of tracking when given the choice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exercising legal rights (e.g., rights granted under the &lt;a href=&#34;https://en.wikipedia.org/wiki/General_Data_Protection_Regulation&#34;&gt;GDPR&lt;/a&gt; or &lt;a href=&#34;https://en.wikipedia.org/wiki/California_Consumer_Privacy_Act&#34;&gt;CCPA&lt;/a&gt;) to remove information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Having a preference for services whose privacy policies indicate less data collection and/or sharing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Turning off telemetry.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;attack-surface&#34;&gt;Attack surface&lt;/h3&gt;
&lt;p&gt;I mentioned content-blocking, which typically happens through browser extensions and/or third-party filter lists. These can add attack surface; be mindful of the trade-off. Even &lt;a href=&#34;https://portswigger.net/research/ublock-i-exfiltrate-exploiting-ad-blockers-with-css&#34;&gt;trusted extensions like uBlock Origin are no exception;&lt;/a&gt; exercise restraint when adding third-party filter lists.&lt;/p&gt;
&lt;p&gt;I covered this topic a bit more in &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;../../04/layered-content-blocking/&#34;&gt;A layered approach to content blocking&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. Safe yet limited approaches to content filtering should lay a foundation, topped off by risky yet powerful approaches that users selectively enable.&lt;/p&gt;
&lt;h2 id=&#34;tracking-evasion-te&#34;&gt;Tracking evasion (TE)&lt;/h2&gt;
&lt;p&gt;&lt;abbr title=&#34;Tracking Evasion&#34;&gt;TE&lt;/abbr&gt; prevents an adversary from collecting meaningful information tied to one&amp;rsquo;s identity. Unlike &amp;ldquo;opting-out&amp;rdquo; and blocking well-known third-party trackers, tracking evasion &lt;em&gt;distrusts all parties by default.&lt;/em&gt; This approach assumes that tracking is equally likely to happen through both first-party and third-party trackers.&lt;/p&gt;
&lt;p&gt;Therefore, a list of known third-party trackers is irrelevant to tracking evasion. Users following this approach in its purest form &lt;em&gt;treat every party capable of tracking as a hostile tracker.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;TE techniques typically revolve around minimizing the size of one&amp;rsquo;s fingerprint, either through fingerprint normalization or randomization.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;sample-te-techniques&#34;&gt;Sample TE techniques&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Using the Tor Browser.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoiding identifiable browser extensions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Randomizing typing behavior (A good example is &lt;a href=&#34;https://github.com/Whonix/kloak&#34;&gt;kloak, a keystroke anonymizer used by Whonix&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/40704&#34;&gt;Using a coarse scroll interval.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;half-measures-are-ineffective&#34;&gt;Half-measures are ineffective&lt;/h3&gt;
&lt;p&gt;If an adversary employs multiple fingerprinting vectors, then normalizing or randomizing a small subset of those vectors might make a user stand out even more.&lt;/p&gt;
&lt;hr /&gt;
&lt;section
	aria-label=&#34;comic, caption, and transcript&#34;
	
	id=&#34;xkcd-1105&#34; tabindex=&#34;-1&#34;&gt;
&lt;h4 id=&#34;infinite-scrolling&#34;&gt;&lt;span&gt;xkcd comic: license plate&lt;/span&gt;&lt;/h4&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_1105_dark.1724299375.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_1105_dark.967318684.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_1105.1170040401.jxl&#34;
type=&#34;image/jxl&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/xkcd_1105.2249198701.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;484&#34; height=&#34;297&#34;
src=&#34;https://envs.net/~seirdy/p/xkcd_1105.2249198701.png&#34; alt=&#34;Comic: a license plate that&amp;#39;s hard to read will be read more carefully by an adversary.&#34;
aria-describedby=&#34;transcript-xkcd-1105&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;A difficult-to-read licence plate number will stand out, putting the owner at risk. Similarly, TE half-measures could make users more easily identifiable. From &lt;a href=&#34;https://xkcd.com/1105/&#34;&gt;xkcd&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;details&gt;
&lt;summary&gt;Toggle comic &lt;span&gt;transcript&lt;/span&gt;&lt;/summary&gt;
&lt;section id=&#34;transcript-xkcd-1105&#34;&gt;
&lt;h5&gt;Comic transcript&lt;/h5&gt;
	&lt;div&gt;
		&lt;p&gt;Cueball is walking in from the right holding a license plate up with both hands for an off-panel Megan to see. It is possible to see the plate, but here it looks like all I&amp;rsquo;s (or 1&amp;rsquo;s).&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Cueball&lt;/dt&gt;
&lt;dd&gt;Check out my personalized license plate!&lt;/dd&gt;
&lt;dt&gt;Megan (off-panel)&lt;/dt&gt;
&lt;dd&gt;&amp;ldquo;1I1-III1&amp;rdquo;?&lt;/dd&gt;
&lt;dt&gt;Cueball&lt;/dt&gt;
&lt;dd&gt;It&amp;rsquo;s perfect!&lt;/dd&gt;
&lt;dt&gt;Cueball&lt;/dt&gt;
&lt;dd&gt;No one will be able to correctly record my plate number!&lt;/dd&gt;
&lt;dt&gt;Cueball&lt;/dt&gt;
&lt;dd&gt;I can commit any crime I want!&lt;/dd&gt;
&lt;dt&gt;Megan&lt;/dt&gt;
&lt;dd&gt;Sounds foolproof.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Soon, at a crime scene:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Witness&lt;/dt&gt;
&lt;dd&gt;The thief&amp;rsquo;s license plate was all &amp;ldquo;1&amp;quot;s or something.&lt;/dd&gt;
&lt;dt&gt;Police officer 1&lt;/dt&gt;
&lt;dd&gt;Oh. &lt;i&gt;That&lt;/i&gt; guy.&lt;/dd&gt;
&lt;dt&gt;Police officer 2&lt;/dt&gt;
&lt;dd&gt;His address is on a post-it in the squad car.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p role=&#34;doc-credit&#34;&gt;Transcript based on the &lt;a href=&#34;https://explainxkcd.com/1105/#Transcript&#34;&gt;explain xkcd wiki entry for xkcd #1105&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/details&gt;

&lt;/section&gt;
&lt;hr /&gt;

&lt;p&gt;TE carries the risk of &amp;ldquo;springing a leak&amp;rdquo;. While TR presents an incremental solution, TE is much harder: it&amp;rsquo;s only a slight exaggeration to describe TE as a binary &amp;ldquo;all-or-nothing&amp;rdquo; approach.&lt;/p&gt;
&lt;h4 id=&#34;other-relevant-discussions-worth-reading&#34;&gt;Other relevant discussions worth reading&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/arkenfox/user.js/issues/1274&#34;&gt;Arkenfox user.js issue 1274: Effort towards a common browser fingerprint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/orgs/privacyguides/discussions/341&#34;&gt;PrivacyGuides discussion 341: Great browser re-write-reboot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conflicts-between-tr-and-te&#34;&gt;Conflicts between TR and TE&lt;/h2&gt;
&lt;p&gt;Good approaches to TR often weaken TE. Conflating the two can have harmful consequences.&lt;/p&gt;
&lt;h3 id=&#34;badness-enumeration-content-blocking&#34;&gt;Badness enumeration: content blocking&lt;/h3&gt;
&lt;p&gt;While content blocking through badness enumeration is useful for TR, it&amp;rsquo;s generally antithetical to TE. A website can use a first-party script and/or inspect server logs to determine information such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Which network requests succeed or fail.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whether certain elements (e.g. certain images) load successfully.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whether injected content (e.g. from an ad-blocker) is present.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whether content-blocking changes which elements are in or near the viewport.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These pieces of information (and others I haven&amp;rsquo;t included) can tell a website if a browser has a content-blocker, and which filters a user has enabled. The latter piece of information can uniquely identify a user; this compromises TE. Nonetheless, these techniques aren&amp;rsquo;t in widespread use. I think that sharing first-party fingerprinting data between different organizations is the exception rather than norm. As long as this is the case, content-blocking remains a viable technique for TR.&lt;/p&gt;
&lt;p&gt;Badness enumeration shouldn&amp;rsquo;t be applied in a TE context. The &lt;a href=&#34;https://2019.www.torproject.org/projects/torbrowser/design/#philosophy&#34;&gt;Tor Browser&amp;rsquo;s design philosophy&lt;/a&gt; explicitly includes a &amp;ldquo;no filters&amp;rdquo; directive and recommends against their use, to reduce fingerprinting. As of mid-2022, the version of the Tor Browser included in &lt;a href=&#34;https://tails.boum.org/&#34;&gt;Tails&lt;/a&gt; includes a content-filtering extension anyway. The entire point of using the Tor Browser Bundle is to maximize TE; Tails compromises this goal.&lt;/p&gt;
&lt;p&gt;Brave has a similar problem. Its content-blocker allows users to create custom filters or activate additional filter lists. Brave also tries to enable TE through fingerprint-randomization. Combining the two likely makes users even more unique. Brave could mitigate this flaw by having its &amp;ldquo;advanced&amp;rdquo; level of fingerprinting protection also normalize the content-blocking filters applied.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;dnt&#34;&gt;Do Not Track (DNT)&lt;/h3&gt;
&lt;p&gt;&lt;abbr title=&#34;Do Not Track&#34;&gt;DNT&lt;/abbr&gt; was an HTTP request header indicating that a user does not wish to be tracked. Unfortunately, unlike &lt;a href=&#34;https://globalprivacycontrol.org/&#34;&gt;Global Privacy Control&lt;/a&gt;, there was no legal obligation to obey DNT. The DNT header ended up being used as a fingerprinting vector to track users instead of a way for them to avoid tracking.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://webkit.org/tracking-prevention/#anti-fingerprinting&#34;&gt;WebKit removed DNT support&lt;/a&gt; because it was antithetical to TE, and its utility for TR was too low to justify these harms.&lt;/p&gt;
&lt;h2 id=&#34;exceptions-and-overlap&#34;&gt;Exceptions and overlap&lt;/h2&gt;
&lt;p&gt;There is grey area between TE and TR. Some techniques don&amp;rsquo;t neatly fit into one of the two categories. Here&amp;rsquo;s an incomplete list of those techniques, for illustrative purposes:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Disabling browser features&lt;/dt&gt;
&lt;dd&gt;The fingerprintability of disabling JavaScript, the &lt;a href=&#34;https://w3c.github.io/reporting/&#34;&gt;Reporting API&lt;/a&gt;, and &lt;a href=&#34;https://html.spec.whatwg.org/multipage/links.html#hyperlink-auditing&#34;&gt;hyperlink auditing&lt;/a&gt; is typically dwarfed by the the fingerprinting made possible by enabling them. I struggle to categorize this technique. On one hand, feature-toggles represent uncommon browser configuration that may prevent some trackers from running (TR); on the other, it treats all external parties equally and can reduce fingerprinting vectors (TE). I&amp;rsquo;m inclined to say that feature-disabling is closer to TE than TR only if enough people share the same configuration.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;dt&gt;Goodness enumeration&lt;/dt&gt;
&lt;dd&gt;Assuming that all actors are actively hostile might be overkill. A user may follow a TE approach and/or disable browser features, while also maintaining a list of trusted exceptions. Trusted sites may use disabled features or have access to a larger fingerprint. This represents a &amp;ldquo;middle ground&amp;rdquo; of sorts between the convenience of TR and the effectiveness of TE.&lt;/dd&gt;
&lt;dt&gt;Amnesia&lt;/dt&gt;
&lt;dd&gt;The most common amnesiac technique is clearing cookies. A more thorough technique is &lt;a href=&#34;https://www.whonix.org/wiki/Qubes/Disposables&#34;&gt;using a disposable VM&lt;/a&gt; that&amp;rsquo;s erased and re-created between sessions. Rather than reduce or evade tracking, these measures reduce the persistence of trackers (and/or malware) that slip through other defenses.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The list goes on. &amp;ldquo;TR versus TE&amp;rdquo; is an important perspective to have, but it isn&amp;rsquo;t the only lens through which we should view privacy-enhancing techniques. Let&amp;rsquo;s be mindful of the TR/TE framework&amp;rsquo;s limitations.&lt;/p&gt;
&lt;h2 id=&#34;how-to-make-privacy-recommendataions&#34;&gt;How to make privacy recommen­dations&lt;/h2&gt;
&lt;p&gt;Privacy-enhancement recommendations need to account for whether a preference for TR over TE exists. Whenever applicable, please do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clarify if a privacy-enhancing technique has a focus on TR or TE.&lt;/li&gt;
&lt;li&gt;When discussing TR techniques, mention any compromises made from a TE perspective.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most importantly: recognize that different people need to make different trade-offs. Someone with special needs might require some fingerprintable personalizations. If non-negotiable personalizations make tracking-evasion too difficult, you might need to steer the person towards tracking-reduction and explain the trade-offs involved.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A single solution isn&amp;rsquo;t enough for everyone. In fact, it&amp;rsquo;s not usually enough for an individual. An individual may switch between multiple tasks, each with a different list of acceptable trade-offs.&lt;/p&gt;
&lt;p&gt;For example, you can encourage people to use multiple browsers and browser-profiles for different needs. Users could use a &amp;ldquo;TR browser&amp;rdquo; to sign into their school or work accounts, but use a &amp;ldquo;TE browser&amp;rdquo; to browse anonymously.&lt;/p&gt;
&lt;p&gt;Personally: my &amp;ldquo;main&amp;rdquo; browser is a heavily personalized Firefox that trades away some security and privacy; where possible, it employs TR. I browse anonymously in the Tor Browser with &amp;ldquo;Safest&amp;rdquo; mode enabled to achieve TE, or using the &amp;ldquo;Safer&amp;rdquo; mode in Whonix. Finally, I use certain web apps in Chromium without any privileged extensions: this trades both convenience and privacy for some forms of security.&lt;/p&gt;
&lt;h3 id=&#34;threat-modelling&#34;&gt;Threat modelling&lt;/h3&gt;
&lt;p&gt;Threat modelling is critical when deciding whether &lt;abbr title=&#34;Tracking Reduction&#34;&gt;TR&lt;/abbr&gt; or &lt;abbr title=&#34;Tracking Evasion&#34;&gt;TE&lt;/abbr&gt; is relevant, and how far one must go to achieve TE. It&amp;rsquo;s slightly less relevant when it comes to deciding which TR techniques are effective. This is because TR involves less advanced threat models and addresses needs that blur the lines between security, privacy, and convenience.&lt;/p&gt;
&lt;p&gt;Rather than framing discussions explicitly in terms of threats, it makes more sense to frame a TR technique in terms of what the technique improves and worsens regarding privacy, security, and convenience. Take what you can get until things get annoying; save extreme measures for a different browser or browser-profile.&lt;/p&gt;
&lt;p&gt;Threat modelling does make sense whenever security trade-offs come into play. It&amp;rsquo;s relevant when evaluating security trade-offs of TR techniques involving privileged extensions.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Communities are starting to understand that recommendations should be made in the context of threat models, and that security- and privacy-related goals are different despite having significant overlap.&lt;/p&gt;
&lt;p&gt;People are complex creatures. When recommending techniques to improve privacy, we should remember that different people have different goals. Moreover, an individual&amp;rsquo;s goals may vary depending on the situation.&lt;/p&gt;
&lt;p&gt;Our recommendations need to take into account the fact that &amp;ldquo;privacy&amp;rdquo; means different things to different people. Techniques that aid in tracking-reduction might weaken tracking-evasion. The latter is much more powerful, but it&amp;rsquo;s also not necessarily what everyone is looking for.&lt;/p&gt;
&lt;section role=&#34;doc-acknowledgments&#34;&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Ack­nowledge­ments&lt;/h2&gt;
&lt;p&gt;My article could be considered a &amp;ldquo;derivative work&amp;rdquo; of &lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://sec.eff.org/articles/recommending-tools&#34;&gt;Recommending Tools&lt;/a&gt;&lt;/cite&gt; by &lt;span&gt;&lt;span&gt;the EFF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. That article laid the foundations for my thought process.&lt;/p&gt;
&lt;p&gt;This article is an expansion of the ideas I presented in the microblog entry &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;../../../../../notes/2022/06/06/on-tracker-blocking/&#34;&gt;On tracker blocking&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. That microblog entry was a response to the article &lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://madaidans-insecurities.github.io/browser-tracking.html&#34;&gt;Browser Tracking&lt;/a&gt;&lt;/cite&gt; by &lt;span 

class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://madaidans-insecurities.github.io/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Madaidan&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;; this article&amp;rsquo;s coverage of TE draws from that article.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I&amp;rsquo;d have liked to call this &amp;ldquo;Tracking prevention&amp;rdquo;. Unfortunately, that name is taken by a Firefox feature aiming to achieve tracking reduction. Naming things is difficult.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I haven&amp;rsquo;t seen much research comparing these two approaches, but I&amp;rsquo;m not convinced they&amp;rsquo;re in conflict. Normalizing all vectors that can be normalized but randomizing the rest sounds like a decent strategy. At least, as long as users don&amp;rsquo;t significantly adjust &lt;em&gt;which&lt;/em&gt; vectors are normalized or randomized.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Sites can detect injected content even without scripts by using Content-Security-Policy reporting APIs. For this reason, uBlock Origin includes a preference to disable all CSP reports. That being said, sites can still use first-party scripts to do the same.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;This is possible without any JavaScript, using lazy-loading directives. Browsers like Firefox disable lazy-loading if JavaScript is also disabled via &lt;code&gt;about:config&lt;/code&gt;, to mitigate this. If JavaScript is enabled, assume this is always a possibility.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;This does present a new issue: filter lists need to get updated at a different cadence than the browser. Not everyone updates at the same time. Imagine that a given browser version at a given time has &lt;var&gt;V&lt;/var&gt; versions of a filter list in use across a user-base. Users have &lt;var&gt;N&lt;/var&gt; different filters enabled. That&amp;rsquo;s &lt;var&gt;V&lt;/var&gt;×&lt;var&gt;N&lt;/var&gt; possible combinations. I&amp;rsquo;m over-simplifying; the point is that filter lists enabled could add significant entropy to a user&amp;rsquo;s fingerprint, and that&amp;rsquo;s before you involve custom filters.&lt;/p&gt;
&lt;p&gt;We could reduce the number of combinations by combining all the filter lists into a single list that gets updated all at once. When &lt;var&gt;N&lt;/var&gt;=1, we&amp;rsquo;re at just &lt;var&gt;V&lt;/var&gt; possible combinations. Updates could be spread out over a longer cadence, decreasing the value of &lt;var&gt;V&lt;/var&gt;.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Torbutton aims to allow many Tor Browser users to share the same configuration. See its &lt;a href=&#34;https://tb-manual.torproject.org/security-settings/&#34;&gt;security settings&lt;/a&gt; and &lt;a href=&#34;https://gitweb.torproject.org/tor-browser.git/tree/browser/components/securitylevel/SecurityLevel.jsm?id=ffdf16f3e8a44b306abd988be874a184b7de1cc6#n273&#34;&gt;the preferences they change&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;Users of metered connections may need to block large elements. Users with accessibility needs may need to alter inaccessible pages. Users who don&amp;rsquo;t speak a page&amp;rsquo;s language may need to use machine translation.&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; Telling users to just &amp;ldquo;stop doing this&amp;rdquo; would be arrogant, yet all three of these examples are fingerprintable.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Copying page text and pasting it into a separate translation tool could help, but it&amp;rsquo;s not always a replacement for full-page translation. &lt;a href=&#34;https://seirdy.one/posts/2020/11/23/website-best-practices/#machine-translation&#34;&gt;Machine translation uses semantic HTML&lt;/a&gt;, and plain-text translation often provides worse results. (ooh, is this my first footnote within a footnote?)&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Best practices for inclusive CLIs</title>
      <link>https://envs.net/~seirdy/posts/2022/06/10/cli-best-practices/</link>
      <pubDate>Sat, 11 Jun 2022 02:24:54 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/06/10/cli-best-practices/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/06/10/cli-best-practices/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2 id=&#34;preface&#34;&gt;Preface&lt;/h2&gt;
&lt;p&gt;This began as a reply to another article by Lucas F. Costa; it lists practices to improve user-experience (&lt;abbr title=&#34;User Experience&#34;&gt;UX&lt;/abbr&gt;) of command-line interfaces (&lt;abbr title=&#34;Command-Line Interface&#34;&gt;CLIs&lt;/abbr&gt;). It comes from a good place, and has some good advice: I particularly like its advice on input-validation and understandable errors. Unfortunately, a number of its suggestions are problematic, particularly from an accessibility perspective.&lt;/p&gt;
&lt;p&gt;This is a &amp;ldquo;living article&amp;rdquo; that I plan on adding to indefinitely. If you like it, come back in a month or two and check the &amp;ldquo;changelog&amp;rdquo; link in the article header.&lt;/p&gt;
&lt;p role=&#34;doc-tip&#34;&gt;Note: this article specifically concerns CLIs, not full-blown textual user interfaces (&lt;abbr title=&#34;Textual User Interfaces&#34;&gt;TUIs&lt;/abbr&gt;). It also focuses on utilities for UNIX-like shells; other command-line environments may have different conventions.&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#problematic-patterns&#34;&gt;Problematic patterns&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#recommendations&#34;&gt;Recommen­dations&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#accessibility&#34;&gt;Accessibility&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#familiarity&#34;&gt;Familiarity&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#documentation&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#miscellaneous&#34;&gt;Miscellaneous&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#more-opinionated-considerations&#34;&gt;More opinionated considerations&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#name-conflicts&#34;&gt;Name conflicts&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#references-and-further-reading&#34;&gt;References and further reading&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;h2 id=&#34;problematic-patterns&#34;&gt;Problematic patterns&lt;/h2&gt;
&lt;p&gt;The &amp;ldquo;Getting Started Experience&amp;rdquo; section of Lucas&amp;rsquo; article has a GIF video of a CLI utility printing &lt;code&gt;--help&lt;/code&gt; output, featuring a decorative border.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-4-caption&#34;&gt;
	&lt;span id=&#34;code-4&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 4&lt;/strong&gt; (&lt;span&gt;console&lt;/span&gt;)&lt;/span&gt;:
Lucas&amp;rsquo; article leads with an example &lt;samp&gt;--help&lt;/samp&gt; output that&amp;rsquo;s surrounded by a decorative textual border. This is a transcription of the output, wrapped to a narrower width.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;samp&gt;$ tool --help

╔ Getting started ════════════════════════════════════════╗
║                                                         ║
║  To scaffold a new project, run:                        ║
║                                                         ║
║    $ mytool init &amp;lt;directory&amp;gt;                            ║
║                                                         ║
║  If you already have a project set up and would like to ║
║  add, remove, or update its structure, run:             ║
║                                                         ║
║    $ mytool manage                                      ║
║                                                         ║
╚═════════════════════════════════════════════════════════╝

Usage: tool &amp;lt;command&amp;gt; [options]
Commands:
  tool init [directory]	creates a new project
  tool manage	allows you to manage an existing project

Options:
  --help	Show help	[boolean]
  --version	Show version number	[boolean]
&lt;/samp&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Borders in TUIs should always be drawn with characters specifically intended for textual interfaces (e.g., boxdraw characters). While I do think the GIF followed this advice, I think it&amp;rsquo;s worth explicitly saying it. Accessible terminal emulators can figure out what these mean and factor them into what they report through an accessibility API. But breaking these borders up with descriptive text makes detection of readable text error-prone.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Borders should be used sparingly, as they end up causing issues when the window is re-sized.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Re-sizing terminal windows is quite common: think about the combined user-base of tiling window managers, tiling terminal session managers (Tmux, Screen, etc.), multiplexing terminal emulators, and plain old split-windows.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Decorative content in CLI output should be limited, since the output of CLI utilities can be piped through other programs. At the very least, these tools should be able to detect whether their standard output is being re-directed or piped and sanitize output accordingly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &amp;ldquo;Colours, Emojis, and Layouting&amp;rdquo; (sic) section has similar issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Nearly all animated spinners are extremely problematic for screenreaders. A simple progress meter and/or numeric percentage combined with flags to enable/disable them is preferable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Excessive animation and color can harm users with attention and/or vestibular disorders, and some on the autism spectrum. Many tools offer a &lt;code&gt;--color[=WHEN]&lt;/code&gt; flag where &lt;code&gt;WHEN&lt;/code&gt; is &lt;code&gt;always&lt;/code&gt;, &lt;code&gt;never&lt;/code&gt;, or &lt;code&gt;auto&lt;/code&gt;. Expecting users to learn all the color configurations for all their tools is unrealistic; tools should &lt;a href=&#34;https://no-color.org/&#34;&gt;respect the &lt;code&gt;NO_COLOR&lt;/code&gt; environment variable.&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;recommendations&#34;&gt;Recommen­dations&lt;/h2&gt;
&lt;p&gt;This is a non-exhaustive list of simple, baseline recommendations for designing CLI utilities.&lt;/p&gt;
&lt;h3 id=&#34;accessibility&#34;&gt;Accessibility&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Send your tool&amp;rsquo;s output through a program like &lt;code&gt;espeak-ng&lt;/code&gt; and listen to it. Can you make sense of the output?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Refer to the latest &lt;abbr title=&#34;Web Content Accessibility Guidelines&#34;&gt;WCAG&lt;/abbr&gt; publication (currently WCAG 2.2) and take a look at the applicable criteria. Many have &lt;a href=&#34;https://w3c.github.io/wcag/techniques/#text&#34;&gt;accompanying techniques for plain-text interfaces.&lt;/a&gt;. Avoiding reliance on color in favor of whitespace and/or indentation for pseudo-headings are two sample recommendations from the WCAG.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure your web-based documentation and forge frontends are accessible, or are mirrored somewhere with good accessibility. I love what the Gitea folks are doing, but sadly their web frontend has a number of critical issues.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; For now, if your forge has accessibility issues, mirroring to GitHub and/or Sourcehut seems like a good option.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid ASCII-art, and use presentational text sparingly. Include a way to configure output to be friendly to screen-readers and log files alike (if it isn&amp;rsquo;t already). For example, a simplified output mode can occasionally log a percentage-complete instead of a progress bar.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;familiarity&#34;&gt;Familiarity&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;How &amp;ldquo;unique&amp;rdquo; is your tool&amp;rsquo;s output? Output should look as similar to other common utilities as possible, to reduce the learning curve. Keep it boring.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow convention: use POSIX-like options. Consider supplementing them with GNU-style long options if your tool has a significant number of them.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid breaking changes to you program&amp;rsquo;s CLI. Remember that its argument parsing is an API, unless documentation explicitly states otherwise.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; Semantic versioning is your friend.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Be predictable. Users expect &lt;code&gt;git log&lt;/code&gt; to print a commit log. Users do not expect &lt;code&gt;git log&lt;/code&gt; to make network connections, write something to their filesystem, etc. Try to only perform the minimum functionality suggested by the command. Naturally, this disqualifies opt-out telemetry.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;documentation&#34;&gt;Documentation&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Write man pages! Man pages have a standardized,&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; predictable, searchable format. Many screen-reader users actually have special scripts to make it easy to read man pages. A man page is also trivial to convert to HTML for people who prefer web-based documentation.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; If your utility has a config file with special syntax or vocabulary, write a dedicated man page for it in section 5 and mention it in a &amp;ldquo;SEE ALSO&amp;rdquo; section.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Try adding shell completions for your program, so users can tab-complete options. This is particularly helpful in shells like Zsh that support help-text in tab completions, especially when combined with plugins like &lt;a href=&#34;https://github.com/Aloxaf/fzf-tab&#34;&gt;fzf-tab&lt;/a&gt; that enable fuzzy-searching help-text (see &lt;a href=&#34;#code-2&#34;&gt;code snippet 2&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Related to no. 2: use a well-understood format for &lt;code&gt;-h&lt;/code&gt; and &lt;code&gt;--help&lt;/code&gt; output. This makes auto-generating shell completions much easier. A great example is the &lt;a href=&#34;https://www.busybox.net/&#34;&gt;Busybox coreutils&amp;rsquo;&lt;/a&gt; help output: it is much more concise than man pages, but descriptive enough to serve as a quick reference. Alternatively, delegate the generation of both to a library that follows this advice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure that the &lt;code&gt;whatis&lt;/code&gt; and &lt;code&gt;apropos&lt;/code&gt; commands work as intended after installing your man pages. These commands parse the beginnings of man pages to give one-line summaries of programs, and often power advanced tab-completion setups.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-5-caption&#34;&gt;
	&lt;span id=&#34;code-5&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 5&lt;/strong&gt; (&lt;span&gt;console&lt;/span&gt;)&lt;/span&gt;:
This is what tab-completion for &lt;a href=&#34;https://sr.ht/~seirdy/MOAC&#34;&gt;MOAC&lt;/a&gt; looks like with fzf-tab.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;samp&gt;$ moac -
&amp;gt; -p
  9/11 (0)
  -P  -- power available to the computer (W)
&amp;gt; -p  -- password to analyze
  -s  -- password entropy
  -h  -- display this help message
  -r  -- interactively enter a password in the terminal; overrides -p
  -T  -- temperature of the system (K)
  -m  -- mass at attacker&#39;s disposal (kg)
  -q  -- account for quantum computers using Grover&#39;s algorithm
&lt;/samp&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;miscellaneous&#34;&gt;Miscellaneous&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Either delegate output wrapping to the terminal, or detect the number of columns and format output to fit. Prefer the former when given a choice, especially when the output is not a TTY.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Be safe. If a tool makes irreversible changes to the outside environment, add a &lt;code&gt;--dry-run&lt;/code&gt; or equivalent option.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If your tool has color output: disable color when the output is not a &lt;a href=&#34;https://en.wikipedia.org/wiki/Tty_%28Unix%29&#34;&gt;TTY&lt;/a&gt;, unless the user explicitly force-enables color via a command-line flag. Many tools support a &lt;code&gt;--color&lt;/code&gt; flag that accepts the values &amp;ldquo;always&amp;rdquo;, &amp;ldquo;never&amp;rdquo;, and &amp;ldquo;auto&amp;rdquo;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;more-opinionated-considerations&#34;&gt;More opinionated considerations&lt;/h2&gt;
&lt;p&gt;These considerations are far more subjective, debatable, and deserving of skepticism than the previous recommendations. There&amp;rsquo;s a reason I call this section &amp;ldquo;considerations&amp;rdquo;, not &amp;ldquo;recommendations&amp;rdquo;. Exceptions abound; I&amp;rsquo;m here to present information, not to think on your behalf.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Remember that users aren&amp;rsquo;t always at their best when they read &lt;code&gt;--help&lt;/code&gt; output; they could be trying to solve a frustrating problem, feeling a great deal of anxiety. Keep the output clean, predictable, boring, and &lt;em&gt;fast.&lt;/em&gt; A 2-second delay and spinning fans will probably be extremely unpleasant for already-stressed users, especially if they need to use it often.&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Include example usage in your man pages and accompanying documentation. Consider submitting the example usage to the &lt;a href=&#34;https://tldr.sh/&#34;&gt;tldr pages&lt;/a&gt; project if your tool gets popular.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Include an extended list of example command invocations and expected output. Make that document double as a test suite. My &lt;a href=&#34;https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac/testdata/scripts&#34;&gt;&lt;code&gt;moac&lt;/code&gt; testdata&lt;/a&gt; and &lt;a href=&#34;https://git.sr.ht/~seirdy/moac/tree/master/item/cmd/moac-pwgen/testdata/scripts&#34;&gt;&lt;code&gt;moac-pwgen&lt;/code&gt; testdata&lt;/a&gt; scripts are good examples. This can serve as a check for API stability, and even as a source of documentation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make your man pages as similar to other man pages on the target OS as possible. Many programs parse man pages, and expect them to follow a predictable structure. Try testing your man pages in multiple programs, just as people test Web pages in multiple browser engines. Some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://manpages.debian.org/unstable/w3m/w3mman.1.en.html&#34;&gt;&lt;code&gt;w3mman&lt;/code&gt;&lt;/a&gt; (included in &lt;a href=&#34;https://github.com/tats/w3m&#34;&gt;w3m&lt;/a&gt;) is a good example to make sure auto-hyperlinking works.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Editors like Vim support looking up man pages for the currently-selected word. Try pressing &lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;k&lt;/kbd&gt; while your caret is on a command name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://pandoc.org/&#34;&gt;Pandoc&lt;/a&gt; is another tool worth testing; it can convert man pages to a variety of different formats.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conform to tools that share a similar niche. If you&amp;rsquo;re using Rust to make a fast alternative to popular coreutils: model its behavior, help-text, and man pages after &lt;code&gt;ripgrep&lt;/code&gt; and &lt;code&gt;fd&lt;/code&gt;. If you&amp;rsquo;re making a linter for Go: copy &lt;code&gt;go vet&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you want to keep your tool simple, make the output readable to both humans and machines; it should work well when streamed to another program&amp;rsquo;s standard input and when parsed by a person. This is especially useful when people redirect output streams to log files, and to screen readers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consider splitting related functionality between many executables (the UNIX way) and/or sub-commands (like Git). I split &lt;a href=&#34;https://sr.ht/~seirdy/MOAC&#34;&gt;MOAC&amp;rsquo;s&lt;/a&gt; functionality across both &lt;code&gt;moac&lt;/code&gt; and &lt;code&gt;moac-pwgen&lt;/code&gt;, and gave &lt;code&gt;moac&lt;/code&gt; three subcommands. The &lt;a href=&#34;https://lucasfcosta.com/2022/06/01/ux-patterns-cli-tools.html#consistent-commands-trees&#34;&gt;&amp;ldquo;Consistent commands trees&amp;rdquo;&lt;/a&gt; section of Lucas&amp;rsquo; article has good advice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don&amp;rsquo;t conflate CLIs and TUIs. A CLI should be non-interactive; a TUI should be interactive. Exceptions exist for really simple interfaces (e.g. Magic-Wormhole and others like it) that accept user input; however, as the interface grows more complex, consider splitting the program into two sibling programs, one of which can have a &amp;ldquo;pure&amp;rdquo; non-interactive CLI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go above and beyond by writing separate integrations for environments like &lt;a href=&#34;https://github.com/tvraman/emacspeak&#34;&gt;Emacspeak&lt;/a&gt;.&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;name-conflicts&#34;&gt;Name conflicts&lt;/h2&gt;
&lt;p&gt;This section might be the most important part of this post. If a CLI executable has a binary name conflict, packagers may have to re-name it. Otherwise, users will have to juggle &lt;code&gt;$PATH&lt;/code&gt; overrides.&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Before publishing your software, test for binary name conflicts. Many package managers have built-in functionality to search for package files. I recommend doing so with large repositories to test for conflicts.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-6-caption&#34;&gt;
	&lt;span id=&#34;code-6&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 6&lt;/strong&gt; (&lt;span&gt;console&lt;/span&gt;)&lt;/span&gt;:
On Fedora and derivatives, use DNF to query package contents. You can also check &lt;samp&gt;cht.sh&lt;/samp&gt; for other common commands.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;samp&gt;$ dnf provides /usr/bin/p
Last metadata expiration check: 0:48:19 ago [...]
perl-App-p-0.0400-19.fc36.noarch : Steroids for your perl one-liners
Repo        : fedora
Matched from:
Filename    : /usr/bin/p

$ curl https://cht.sh/fly
# fly
# Command-line tool for concourse-ci.
# More information: &amp;lt;https://concourse-ci.org/fly.html&amp;gt;.
[...]
&lt;/samp&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;p&gt;Thanks to Emily for &lt;a href=&#34;https://web.archive.org/web/20221117231326/https://sparkly.uni.horse/@emily/108451871152495325&#34;&gt;reminding me of name conflicts.&lt;/a&gt;&lt;/p&gt;
&lt;section role=&#34;doc-bibliography&#34;&gt;
&lt;h2 id=&#34;references-and-further-reading&#34;&gt;References and further reading&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;Harini Sampath, Alice Merrick, and Andrew Macvean. 2021. &lt;em&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://dl.acm.org/doi/fullHtml/10.1145/3411764.3445544&#34;&gt;Accessibility of Command Line Interfaces&lt;/a&gt;&lt;/cite&gt;. In CHI Conference on Human Factors in Computing Systems (CHI &amp;lsquo;21), May 8–13, 2021, Yokohama, Japan.&lt;/em&gt; ACM, New York, NY, USA 10 Pages. &lt;a href=&#34;https://doi.org/10.1145/3411764.3445544&#34;&gt;DOI 10.1145/&lt;wbr /&gt;3411764.3445544&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/#text&#34;&gt;Techniques for WCAG 2.2&lt;/a&gt;&lt;/cite&gt;. Alastair Campbell, Michael Cooper, Andrew Kirkpatrick. W3C. &lt;time datetime=&#34;2022-05-30&#34;&gt;2022-05-30&lt;/time&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://clig.dev/&#34;&gt;Command Line Interface Guidelines&lt;/a&gt;&lt;/cite&gt;. Aanand Prasad, Ben Firshman, Carl Tashian, Eva Parish. Commit &lt;code&gt;89d755c&lt;/code&gt;, &lt;time datetime=&#34;2022-04-19&#34;&gt;2022-04-19&lt;/time&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Yes, it&amp;rsquo;s possible to support re-sizing by using a TUI library like ncurses. Unfortunately, TUIs are out of scope for this article; I&amp;rsquo;m focusing mainly on CLIs.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://web.archive.org/web/20220725162250/https://mastodon.technology/@codeberg/108403449317373462&#34;&gt;this Fediverse thread&lt;/a&gt; about forge accessibility.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;I need to take my own advice for programs like &lt;a href=&#34;https://sr.ht/~seirdy/MOAC&#34;&gt;MOAC&lt;/a&gt;. Ugh.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;For a good example, see Git&amp;rsquo;s distinction between regular output and porcelain-friendly output. The instability of the former and stability of the latter are explicitly documented in the Git man pages and in the official Git book.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Well, they&amp;rsquo;re &lt;em&gt;somewhat&lt;/em&gt; standardized compared to plain stdout.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://seirdy.one/posts/2020/11/23/website-best-practices/&#34;&gt;My other article on accessible textual websites&lt;/a&gt; is probably relevant when it comes to Web-based documentation&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;For more on man page sections, see the &lt;a href=&#34;https://man.openbsd.org/man&#34;&gt;&lt;code&gt;man(1)&lt;/code&gt;&lt;/a&gt; man page.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;The slow responses to basic flags like &lt;code&gt;--help&lt;/code&gt; is one of many reasons I dislike Java command-line utilities (signal-cli, Nu HTML Checker). I believe I&amp;rsquo;m not alone when I say this.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;I used to not-very-seriously claim that Neovim, my preferred &lt;code&gt;$EDITOR&lt;/code&gt;, is better than Emacs. Then I tried Emacspeak. I still make the same claim, but more softly and with an exception for Emacspeak.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;A notable exception is executables that are supposed to conflict with others. Distributions like Fedora, Debian, and derivatives have an &amp;ldquo;alternatives&amp;rdquo; system to manage these overrides using symlinks. Examples include toolchains (&lt;code&gt;cc&lt;/code&gt; and &lt;code&gt;ld&lt;/code&gt; could point to their GCC or Clang implementations) and mail transfer agents (&lt;code&gt;sendmail&lt;/code&gt; and &lt;code&gt;mta&lt;/code&gt; have been re-implemented many times over).&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>A layered approach to content blocking</title>
      <link>https://envs.net/~seirdy/posts/2022/06/04/layered-content-blocking/</link>
      <pubDate>Sun, 05 Jun 2022 05:47:00 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/06/04/layered-content-blocking/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/06/04/layered-content-blocking/">&lt;p&gt;The Chromium team is planning on phasing out Manifest V2, its current set of extension APIs, in favor of Manifest V3. &lt;a href=&#34;https://developer.chrome.com/docs/extensions/mv3/intro/&#34;&gt;Manifest V3&lt;/a&gt; involves giving extensions less access to page contents. Instead, extensions use new APIs that involve giving the browser simple instructions for page modification. The browser performs those instructions using its own logic; extensions themselves can&amp;rsquo;t access page contents.&lt;/p&gt;
&lt;p&gt;This represents a tremendous trade-off: extensions need to be trusted less, but are also less capable. The implications for content blockers (ad-blockers) caused significant backlash.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Mozilla plans on adopting Manifest V3 in Firefox with additional APIs to re-introduce the lost functionality. Discourse on the topic has been polarized, full of oversimplification, and devoid of nuance.&lt;/p&gt;
&lt;p&gt;My views on the situation are a bit complicated.&lt;/p&gt;
&lt;h2 id=&#34;the-existing-content-filtering-landscape&#34;&gt;The existing content filtering landscape&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/gorhill/uBlock&#34;&gt;uBlock Origin&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; has advanced content filters, with the ability to inject near-arbitrary stylesheets and a number of scripts into pages. Injecting scripts and stylesheets is often necessary to bypass malicious &amp;ldquo;anti-adblock&amp;rdquo; scripts or to skip certain types of video ads on streaming platforms. Unfortunately, this presents a security risk: users must trust every filter to not inject malicious stylesheets. Furthermore, sometimes these extensions don&amp;rsquo;t run their filters &amp;ldquo;in time&amp;rdquo;; a delay in running a filter could allow unwanted content to sneak through. This is especially common during browser launch. Nonetheless, its functionality makes the user-hostile Web considerably less frustrating, and I rely on it every day.&lt;/p&gt;
&lt;p&gt;Chromium&amp;rsquo;s Manifest v3 includes the &lt;code&gt;declarativeNetRequest&lt;/code&gt; API, which delegates these functions to the browser rather than the extension. Doing so avoids the timing issues visible in privileged extensions and does not require giving the extension access to the page. While these filters are more reliable and improve privilege separation, they are also substantially weaker. You can say goodbye to more advanced &amp;ldquo;anti-adblock&amp;rdquo; circumvention techniques.&lt;/p&gt;
&lt;p&gt;Hostname or IP-based based network filtering is the least capable but most reliable approach. Filters are limited to domain names (i.e. you can&amp;rsquo;t block individual paths from a domain or make cosmetic filters), and they run unconditionally and globally. However, they don&amp;rsquo;t introduce nearly the same attack surface as other methods. When combined with CNAME-uncloaking, they&amp;rsquo;re quite effective at what (little) they do. The best part is that they carry little to no overhead; these lists can scale to millions of domains if applied on the DNS level.&lt;/p&gt;
&lt;h2 id=&#34;context-extension-permissions-systems&#34;&gt;Context: extension permissions systems&lt;/h2&gt;
&lt;p&gt;Firefox allows extensions to declare their own permissions. Extensions decide which sites they can run on and when, with required and optional permissions.&lt;/p&gt;
&lt;p&gt;Chromium has a similar system with additional functionality: users can choose to enable an extension only when clicked, only for a certain site, or for all sites globally. Safari takes this a step further and also offers the choice to enable an extension for a limited time period (one day).&lt;/p&gt;
&lt;p&gt;On Firefox, users of an extension like Stylus&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; would need to grant the extension access to every page. On Chromium, users only need to grant it access to the subset of pages they need to theme.&lt;/p&gt;
&lt;h2 id=&#34;a-layered-approach-to-content-filtering&#34;&gt;A layered approach to content filtering&lt;/h2&gt;
&lt;p&gt;I think content filtering should follow a layered approach. It can have three layers:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;dfn&gt;Coarse network filters&lt;/dfn&gt;&lt;/dt&gt;
&lt;dd&gt;These can be DNS- or IP-based filters that run globally. They can be applied to an entire network, a device, and/or a given network namespace.&lt;/dd&gt;
&lt;dt&gt;&lt;dfn&gt;Declarative filters&lt;/dfn&gt;&lt;/dt&gt;
&lt;dd&gt;Simple content-blocking rules that are parsed and enforced by the user-agent. These filters can be restricted to safe blocking rules that don&amp;rsquo;t inject content into pages.&lt;/dd&gt;
&lt;dt&gt;&lt;dfn&gt;Privileged extensions&lt;/dfn&gt;&lt;/dt&gt;
&lt;dd&gt;The most powerful and most risky types of page alteration, containing Turing-complete logic. These can make arbitrary page alterations, edit cookie contents, inject scripts and stylesheets, and re-write request URLs. These extensions can alter a page&amp;rsquo;s Content Security Policy to allow running injected scripts.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;DNS- or IP-based filters can run system-wide, and be limited to safe filters that are unlikely to trigger site breakages. Atop these filters, browsers can globally enable extensions that use declarative filters. A browser could be configured to ignore global hostname or IP filters that are already covered by the aforementioned system-wide filters; doing so could improve performance when users enable a high number of filters.&lt;/p&gt;
&lt;p&gt;Users can then choose to selectively enable a privileged extension (such as uBlock Origin) only on sites that continue to misbehave, using something resembling Chromium&amp;rsquo;s extension permission system. Privileged extensions can perform any functionality not covered by the previous two layers. Selectively enabling them significantly reduces attack surface without crippling the ability to modify content.&lt;/p&gt;
&lt;h3 id=&#34;the-safe-layers-network-and-declarative-filters&#34;&gt;The safe layers: network and declarative filters&lt;/h3&gt;
&lt;p&gt;Say a user visits a typical site containing JavaScript and/or WebAssembly, some of which is malicious.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; System-wide network filters can block domains serving third-party malware, such as Google Ads or Google Analytics. Overly security conscious users can use built-in browser functionality to block cookies and scripts by default, and enable them on a site-by-site basis.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A user might need to enable these scripts, or some malware might sneak through coarse network filters as first-party content. The site may contain other pure HTML- and CSS-based annoyances like &amp;ldquo;sign up&amp;rdquo; modals, cookie notices, sticky headers, &lt;a href=&#34;https://daringfireball.net/linked/2011/03/06/dickbar&#34;&gt;dickbars&lt;/a&gt;, etc. Declarative filters serve as a second layer of defense to handle these.&lt;/p&gt;
&lt;h3 id=&#34;the-advanced-layer-privileged-extensions&#34;&gt;The advanced layer: privileged extensions&lt;/h3&gt;
&lt;p&gt;The final layer is advanced page alteration. Anti-adblock software is the most common offender, but other examples exist.&lt;/p&gt;
&lt;p&gt;A page may use a single blob of JavaScript that contains both malware and essential functionality. Simply blocking the script will break the page, but allowing it would cause a user&amp;rsquo;s device to perform an unwanted action. It&amp;rsquo;s unreasonable to expect users to reverse-engineer every obfuscated script they come across; plenty would appreciate some sort of automatic filtering.&lt;/p&gt;
&lt;p&gt;Maybe the page contains a JavaScript video player with auto-playing media, and the user wants to block auto-playing videos conditionally. The user might have enabled auto-playing videos for the site&amp;rsquo;s &amp;ldquo;videos&amp;rdquo; section but wish to disable auto-playing for its &amp;ldquo;articles&amp;rdquo; section.&lt;/p&gt;
&lt;p&gt;An extension that can access the page, inject its content, and use complex logic to alter the page can fix these problems. It could replace a malicious script with an alternative that provides the necessary functionality while stubbing off malicious functionality, alter cookies that power paywalls triggered after a given number of &amp;ldquo;articles read&amp;rdquo;, or change video player states based on the video&amp;rsquo;s metadata.&lt;/p&gt;
&lt;p&gt;One example I find particularly interesting: a friend of mine has been working on an extension to only load animated GIFs conditionally. Some animated GIFs are fine, but others contain flashing colors that we consider to be overstimulating.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; The extension would disable auto-playing GIFs and inspect each one. After inspecting a GIF, it would animate it if consecutive frames fall below a given contrast ratio.&lt;/p&gt;
&lt;p&gt;Several more examples are available in &lt;a href=&#34;https://github.com/gorhill/uBlock/wiki/Resources-Library&#34;&gt;uBlock Origin&amp;rsquo;s resource library&lt;/a&gt;. Much of this functionality would be unavailable to Manifest V3 extensions in Chromium.&lt;/p&gt;
&lt;h2 id=&#34;frequently-asked-questions&#34;&gt;Frequently-asked questions&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll update this section as I collect feedback. Watch this space.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;q&gt;Malicious extensions can still request permission to read the contents of the page. What have you done differently besides adding new APIs?&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;The difference is that these malicious extensions will require the extra permission to access your data for all websites, while extensions using declarative APIs will not. Security-conscious users can keep that fact in mind. However, we shouldn&amp;rsquo;t speak for other users with different priorities.
&lt;p&gt;I imagine that &lt;a href=&#34;https://web.archive.org/web/20220607001654/https://hexavalent.org/&#34;&gt;an opinionated security-focused browser&lt;/a&gt; could make it possible for users to enable privileged extensions only on a site-by-site basis, for those interested &lt;ins&gt;(Update: Hexavalent has been discontinued)&lt;/ins&gt;. Personally, I think that it&amp;rsquo;s probably best to limit scriptlet injection to signed scripts.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Another difference is that while declarative filtering does have reduced functionality, it&amp;rsquo;s also more effective in some ways. Declarative filters generally have a lower footprint and are less likely to experience the delayed execution that lets some unwanted content slip through.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;q&gt;If we trust our extension developers, is any of this really necessary?&lt;/q&gt;&lt;/dt&gt;
&lt;dd&gt;With adblockers, you don&amp;rsquo;t just trust extension developers; you also trust filter-list contributors. Many filter lists have thousands of entries aggregated from other filter lists, so trust-by-proxy ends up covering a lot of ground. This also applies to userstyle extensions: you have to trust the authors of each theme.
&lt;p&gt;CSS injection is a powerful tool that can be used well or maliciously. Remember that its contributors and extension developers could be well-meaning but still allow a vulnerability to slip through, especially when you account for extensions that alter a site&amp;rsquo;s CSP.&lt;/p&gt;
&lt;p&gt;I still use these privileged extensions, but I try to limit their scope to sites where they&amp;rsquo;re necessary.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;I don&amp;rsquo;t think Manifest V3 can replace Manifest V2&amp;rsquo;s privileged extensions,&lt;/strong&gt; and &lt;strong&gt;I don&amp;rsquo;t think existing APIs should be removed without replacement.&lt;/strong&gt; However, that doesn&amp;rsquo;t mean V3&amp;rsquo;s APIs can&amp;rsquo;t be useful. While its scope is smaller, its blocking is safer and more reliable. Declarative approaches work well as a complement to other content-blocking techniques in a layered approach to content blocking. I felt the need to write up my thoughts because they didn&amp;rsquo;t fit in with the current polarized discourse around content blocking.&lt;/p&gt;
&lt;p&gt;Rather than using a single tool to perform all content filtering, we should try moving towards a layered approach. Each type of filter should be delegated to the tool best suited for the task. Users should have control over the scope of each layer.&lt;/p&gt;
&lt;!--
	Topics I should probably mention for completeness:
	- TLS terminating proxies that alter content
	- corporate firewalls that block domains
	- Maaaaybe make analogy that compares &#34;dark mode&#34; extensions with forced-colors (Firefox browser feature, Windows system-wide feature inc. browsers (High Contrast Mode). forced colors is like the declarative approach and much more &#34;effective&#34; and doesn&#39;t require granting extra access but also more coarse/less advanced. I&#39;m worried I&#39;ll get sidetracked tho :|
--&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I can already hear adtech-defenders typing a response that explains why choosing how to render downloaded content is problematic or unethical.&lt;/p&gt;
&lt;p&gt;Users don&amp;rsquo;t know the contents of a resource before fetching it, so they can&amp;rsquo;t provide meaningful consent to any malicious behavior in said contents (e.g. tracking). Content providers must therefore respect user control over downloaded content if such networks are to function.&lt;/p&gt;
&lt;p&gt;I start from the notion that when a user downloads a document, they are entitled to do what they wish with it. If it&amp;rsquo;s broken or malicious, they should be able to fix it. When it comes to accessibility&amp;mdash;especially regarding cognitive accessibility for ADHD and anxiety disorders&amp;mdash;content blocking isn&amp;rsquo;t always optional.&lt;/p&gt;
&lt;p&gt;Browsers don&amp;rsquo;t download a rendered page; they download source code. It&amp;rsquo;s up to the user agent to choose if or how that code renders. As long as users can control their means to browse the web, content &amp;ldquo;alteration&amp;rdquo; is a part of the package.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Not to be confused with the &lt;a href=&#34;https://github.com/gorhill/uBlock/wiki/uBlock-Origin-is-completely-unrelated-to-the-web-site-ublock.org&#34;&gt;unrelated extension called &amp;ldquo;uBlock&amp;rdquo;&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Stylus is an extension that allows injecting special stylesheets (called &amp;ldquo;userstyles&amp;rdquo;) into pages to change their appearance. Stylesheets can be applied to specific pages, pages matching a pattern, or globally.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;I use the term &amp;ldquo;malicious&amp;rdquo; loosely here. These scripts could perform tracking without prior informed consent or attempt to distract the user with ads, both of which are malicious.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Chromium offers this functionality. If users choose to block all cookies, it exposes controls to allow cookies for the current site that last for the current session or persist until they expire. It offers a similar site-specific toggle for JavaScript. As far as I am aware, Firefox does not expose controls for managing these permissions on the current page: users need to open the preferences page every time they wish to add such a rule, or use a privileged extension. &lt;ins datetime=&#34;2024-07-02&#34;&gt;Update &lt;time&gt;2024-07-02&lt;/time&gt;: &lt;span&gt;Firefox does support per-site cookie settings via the site permissions menu, accessible via Page Info. Thanks Noah!&lt;/span&gt;&lt;/ins&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Animated custom emotes are a common offender, especially when a post contains several consecutive ones.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;One point of controversy is that major browsers only allow extensions signed by the browser vendor&amp;rsquo;s key. I think this is a legitimate concern, best solved by allowing users to easily specify an alternative signing key and sign extensions themselves.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>The right thing for the wrong reasons: FLOSS doesn&#39;t imply security</title>
      <link>https://envs.net/~seirdy/posts/2022/02/02/floss-security/</link>
      <pubDate>Wed, 02 Feb 2022 23:16:00 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2022/02/02/floss-security/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2022/02/02/floss-security/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;I find it quite easy to handle views different from my own. I feel more troubled when I see people agree with me for the wrong reasons.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s no secret that I&amp;rsquo;m a passionate supporter of software freedom: I&amp;rsquo;ve written two posts about how Free, Libre, and Open-Source software (&lt;abbr title=&#34;Free, Libre, and Open-Source Software&#34;&gt;FLOSS&lt;/abbr&gt;) is necessary but insufficient to preserve user autonomy:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;../../../../2021/01/27/whatsapp-and-the-domestication-of-users/&#34;&gt;Whatsapp and the domestication of users&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The phenomenon of a class of predatory businesses models I call &amp;ldquo;user domestication&amp;rdquo; and defense measures: FLOSS, open platforms, and simplicity.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;../../../../2021/02/23/keeping-platforms-open/&#34;&gt;Keeping platforms open&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;How open platforms can lose their openness, and what measures can prevent this. The Web, XMPP, email, and Matrix are examples that highlight both sides of the issue.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;After two posts spanning over 5000 words, I need to add some nuance.&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#introduction&#34;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#how-security-fixes-work&#34;&gt;How security fixes work&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#reverse-engineering&#34;&gt;Reverse engineering&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#special-builds&#34;&gt;Special builds&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#dynamic-analysis&#34;&gt;Dynamic analysis&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#binary-analysis&#34;&gt;Binary analysis&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#example-malware-analysis&#34;&gt;Example: malware analysis&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#extreme-example-the-truth-about-intel-me-and-amt&#34;&gt;Extreme example: the truth about Intel ME and AMT&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#fuzzing&#34;&gt;Fuzzing&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#example-cve-wbr-2022-0185&#34;&gt;Example: CVE-&lt;wbr /&gt;2022-0185&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#good-counter-arguments&#34;&gt;Good counter-arguments&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#conclusion&#34;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;One of the biggest parts of the Free and Open Source Software definitions is the freedom to study a program and modify it; in other words, access to editable source code. I agree that such access is essential; however, far too many people support source availability for the &lt;em&gt;wrong&lt;/em&gt; reasons. One such reason is that source code is necessary to have any degree of transparency into how a piece of software operates, and is therefore necessary to determine if it is at all secure or trustworthy. Although security through obscurity is certainly not a robust measure, this claim has two issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source code describes what a program is designed to do; it is unnecessary and insufficient to determine if what it actually does aligns with its intended design.&lt;/li&gt;
&lt;li&gt;Vulnerability discovery doesn&amp;rsquo;t require source code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;d like to expand on these issues, focusing primarily on compiled binaries. Bear in mind that I do not think that source availability is &lt;em&gt;useless&lt;/em&gt; from a security perspective (it certainly makes audits easier), and I &lt;em&gt;do&lt;/em&gt; think that source availability is required for user freedom. I&amp;rsquo;m arguing only that &lt;strong&gt;source unavailability doesn&amp;rsquo;t imply insecurity&lt;/strong&gt;, and &lt;strong&gt;source availability doesn&amp;rsquo;t imply security&lt;/strong&gt;. It&amp;rsquo;s possible (and often preferable) to perform security analysis on binaries, without necessarily having source code. In fact, vulnerability discovery doesn&amp;rsquo;t typically rely upon source code analysis.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll update this post occasionally as I learn more on the subject. If you like it, check back in a month or two to see if it has something new.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;PS: this stance is not absolute; I concede to several &lt;a href=&#34;#good-counter-arguments&#34;&gt;good counter-arguments in a dedicated section&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;how-security-fixes-work&#34;&gt;How security fixes work&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t think anyone seriously claims that software&amp;rsquo;s security instantly improves the second its source code is published. The argument I&amp;rsquo;m responding to is that source code is necessary to understand what a program does and how (in)secure it is, and without it we can&amp;rsquo;t know for sure.&lt;/p&gt;
&lt;p&gt;Assuming a re-write that fundamentally changes a program&amp;rsquo;s architecture is not an option&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, software security typically improves by fixing vulnerabilities via something resembling this process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Someone discovers a vulnerability&lt;/li&gt;
&lt;li&gt;Developers are informed of the vulnerability&lt;/li&gt;
&lt;li&gt;Developers reproduce the issue and understand what caused it&lt;/li&gt;
&lt;li&gt;Developers patch the software to fix the vulnerability&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Source code is typically helpful (sometimes essential) to Step 3. If someone has completed Step 3, they will require source code to proceed to Step 4. Source code &lt;em&gt;isn&amp;rsquo;t necessary for Steps 1 and 2&lt;/em&gt;; these steps rely upon understanding how a program misbehaves. For that, we use &lt;em&gt;reverse engineering&lt;/em&gt; and/or &lt;em&gt;fuzzing&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;reverse-engineering&#34;&gt;Reverse engineering&lt;/h2&gt;
&lt;p&gt;Understanding &lt;em&gt;how a program is designed&lt;/em&gt; is not the same as understanding &lt;em&gt;what a program does.&lt;/em&gt; A reasonable level of one type of understanding does not imply the other.&lt;/p&gt;
&lt;p&gt;Source code&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; is essential to describe a program&amp;rsquo;s high-level, human-comprehensible design; it represents a contract that outlines how a developer &lt;em&gt;expects&lt;/em&gt; a program to behave. A compiler or interpreter&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; must then translate it into machine instructions. But source code isn&amp;rsquo;t always easy to map directly to machine instructions because it is part of a complex system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Compilers (sometimes even interpreters) can apply optimizations and hardening measures that are difficult to reason about. This is especially true for &lt;abbr title=&#34;Just-In-Time&#34;&gt;JIT&lt;/abbr&gt; compilers that leverage run-time information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The operating system itself may be poorly understood by the developers, and run a program in a way that contradicts a developer&amp;rsquo;s expectations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Toolchains, interpreters, and operating systems can have bugs that impact program execution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Different compilers and compiler flags can offer different security guarantees and mitigations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Source code can be deceptive by featuring sneaky obfuscation techniques, sometimes unintentionally. Confusing naming patterns, re-definitions, and vulnerabilities masquerading as innocent bugs have all been well-documented: look up &amp;ldquo;hypocrite commits&amp;rdquo; or the &lt;a href=&#34;https://en.wikipedia.org/wiki/Underhanded_C_Contest&#34;&gt;Underhanded C Contest&lt;/a&gt; for examples.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All of the above points apply to each dependency and the underlying operating system, which can impact a program&amp;rsquo;s behavior.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Furthermore, all programmers are flawed mortals who don&amp;rsquo;t always fully understand source code. Everyone who&amp;rsquo;s done a non-trivial amount of programming is familiar with the feeling of encountering a bug during run-time for which the cause is impossible to find&amp;hellip;until they notice it staring them in the face on Line 12. Think of all the bugs that &lt;em&gt;aren&amp;rsquo;t&lt;/em&gt; so easily noticed.&lt;/p&gt;
&lt;p&gt;Reading the source code, compiling, and passing tests isn&amp;rsquo;t sufficient to show us a program&amp;rsquo;s final behavior. The only way to know what a program does when you run it is to&amp;hellip;run it.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;special-builds&#34;&gt;Special builds&lt;/h3&gt;
&lt;p&gt;Almost all programmers are fully aware of their limited ability, which is why most already employ techniques to analyze run-time behavior that don&amp;rsquo;t depend on source code. For example, developers of several compiled languages&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; can build binaries with sanitizers to detect undefined behavior, races, uninitialized reads, etc. that human eyes may have missed when reading source code. While source code is necessary to &lt;em&gt;build&lt;/em&gt; these binaries, it isn&amp;rsquo;t necessary to run them and observe failures.&lt;/p&gt;
&lt;p&gt;Distributing binaries with sanitizers and debug information to testers is a valid way to collect data about a program&amp;rsquo;s potential security issues.&lt;/p&gt;
&lt;h3 id=&#34;dynamic-analysis&#34;&gt;Dynamic analysis&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s hard to figure out which syscalls and files a large program program needs by reading its source, especially when certain libraries (e.g. the libc implementation/version) can vary. A syscall tracer like &lt;a href=&#34;https://strace.io/&#34;&gt;&lt;code&gt;strace(1)&lt;/code&gt;&lt;/a&gt;&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; makes the process trivial.&lt;/p&gt;
&lt;p&gt;A personal example: the understanding I gained from &lt;code&gt;strace&lt;/code&gt; was necessary for me to write &lt;a href=&#34;https://sr.ht/~seirdy/bwrap-scripts/&#34;&gt;my bubblewrap scripts&lt;/a&gt;. These scripts use &lt;a href=&#34;https://github.com/containers/bubblewrap&#34;&gt;&lt;code&gt;bubblewrap(1)&lt;/code&gt;&lt;/a&gt; to sandbox programs with the minimum permissions possible. Analyzing every relevant program and library&amp;rsquo;s source code would have taken me months, while &lt;code&gt;strace&lt;/code&gt; gave me everything I needed to know in an afternoon: analyzing the &lt;code&gt;strace&lt;/code&gt; output told me exactly which syscalls to allow and which files to grant access to, without even having to know what language the program was written in. I generated the initial version of the syscall allow-lists with the following command&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;strace name-of-program program-args 2&amp;gt;&amp;amp;1 \
	| rg &#39;^([a-z_]*)\(.*&#39; --replace &#39;$1&#39; \
	| sort | uniq
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also extends to determining how programs utilize the network: packet sniffers like &lt;a href=&#34;https://www.wireshark.org/&#34;&gt;Wireshark&lt;/a&gt; can determine when a program connects to the network, and where it connects.&lt;/p&gt;
&lt;p&gt;These methods are not flawless. Syscall tracers are only designed to shed light on how a program interacts with the kernel. Kernel interactions tell us plenty (it&amp;rsquo;s sometimes all we need), but they don&amp;rsquo;t give the whole story. Furthermore, packet inspection can be made a bit painful by transit encryption&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;; tracing a program&amp;rsquo;s execution alongside packet inspection can offer clarity, but this is not easy.&lt;/p&gt;
&lt;p&gt;For more information, we turn to &lt;a href=&#34;https://en.wikipedia.org/wiki/Core_dump&#34;&gt;&lt;strong&gt;core dumps&lt;/strong&gt;&lt;/a&gt;, also known as memory dumps. Core dumps share the state of a program during execution or upon crashing, giving us greater visibility into exactly what data a program is processing. Builds containing debugging symbols (e.g. &lt;a href=&#34;https://dwarfstd.org/&#34;&gt;DWARF&lt;/a&gt;) have more detailed core dumps. Vendors that release daily snapshots of pre-release builds typically include some symbols to give testers more detail concerning the causes of crashes. Web browsers are a common example: Chromium dev snapshots, Chrome Canary, Firefox Nightly, WebKit Canary builds, etc. all include debug symbols. &lt;a href=&#34;https://twitter.com/MisteFr/status/1168597562703716354?s=20&#34;&gt;Until 2019, &lt;em&gt;Minecraft: Bedrock Edition&lt;/em&gt; included debug symbols&lt;/a&gt; which were used heavily by the modding community.&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h4 id=&#34;dynamic-analysis-example-zoom&#34;&gt;Dynamic analysis example: Zoom&lt;/h4&gt;
&lt;p&gt;In 2020, Zoom Video Communications came under scrutiny for marketing its &amp;ldquo;Zoom&amp;rdquo; software as a secure, end-to-end encrypted solution for video conferencing. Zoom&amp;rsquo;s documentation claimed that it used &amp;ldquo;AES-256&amp;rdquo; encryption. Without source code, did we have to take the docs at their word?&lt;/p&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;a href=&#34;https://citizenlab.ca/&#34;&gt;&lt;span&gt;The Citizen Lab&lt;/span&gt;&lt;/a&gt; didn&amp;rsquo;t. On &lt;time class=&#34;dt-published published&#34;&gt;2020-04-03&lt;/time&gt;, it published &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://citizenlab.ca/2020/04/move-fast-roll-your-own-crypto-a-quick-look-at-the-confidentiality-of-zoom-meetings/&#34;&gt;Move Fast and Roll Your Own Crypto&lt;/a&gt;&lt;/cite&gt; (&lt;span&gt;application/pdf&lt;/span&gt;)&lt;/span&gt; revealing critical flaws in Zoom&amp;rsquo;s encryption. It utilized Wireshark and &lt;a href=&#34;https://mitmproxy.org/&#34;&gt;mitmproxy&lt;/a&gt; to analyze networking activity, and inspected core dumps to learn about its encryption implementation. The Citizen Lab&amp;rsquo;s researchers found that Zoom actually used an incredibly flawed implementation of a weak version of AES-128 (ECB mode), and easily bypassed it.&lt;/p&gt;
&lt;p&gt;Syscall tracing, packet sniffing, and core dumps are great, but they rely on manual execution which might not hit all the desired code paths. Fortunately, there are other forms of analysis available.&lt;/p&gt;
&lt;h3 id=&#34;binary-analysis&#34;&gt;Binary analysis&lt;/h3&gt;
&lt;p&gt;Tracing execution and inspecting memory dumps can be considered forms of reverse engineering, but they only offer a surface-level view of what&amp;rsquo;s going on. Reverse engineering gets much more interesting when we analyze a binary artifact.&lt;/p&gt;
&lt;p&gt;Static binary analysis is a powerful way to inspect a program&amp;rsquo;s underlying design. Decompilation (especially when supplemented with debug symbols) can re-construct a binary&amp;rsquo;s assembly or source code. Symbol names may look incomprehensible in stripped binaries, and comments will be missing. What&amp;rsquo;s left is more than enough to decipher control flow to uncover how a program processes data. This process can be tedious, especially if a program uses certain forms of binary obfuscation.&lt;/p&gt;
&lt;p&gt;The goal doesn&amp;rsquo;t have to be a complete understanding of a program&amp;rsquo;s design (incredibly difficult without source code); it&amp;rsquo;s typically to answer a specific question, fill in a gap left by tracing/fuzzing, or find a well-known property. When developers publish documentation on the security architecture of their closed-source software, reverse engineering tools like decompilers are exactly what you need to verify their honesty (or lack thereof).&lt;/p&gt;
&lt;p&gt;Decompilers are seldom used alone in this context. Instead, they&amp;rsquo;re typically a component of reverse engineering frameworks that also sport memory analysis, debugging tools, scripting, and sometimes even IDEs. I use &lt;a href=&#34;https://rizin.re/&#34;&gt;the Rizin framework&lt;/a&gt;, but &lt;a href=&#34;https://ghidra-sre.org/&#34;&gt;Ghidra&lt;/a&gt; is also popular. Their documentation should help you get started if you&amp;rsquo;re interested.&lt;/p&gt;
&lt;h3 id=&#34;example-malware-analysis&#34;&gt;Example: malware analysis&lt;/h3&gt;
&lt;p&gt;These reverse-engineering techniques&amp;mdash;a combination of tracing, packet sniffing, binary analysis, and memory dumps&amp;mdash;make up the workings of most modern malware analysis. See &lt;a href=&#34;https://www.hybrid-analysis.com/sample/1ef3b7e9ba5f486afe53fcbd71f69c3f9a01813f35732222f64c0981a0906429/5e428f69c88e9e64c33afe64&#34;&gt;this example of a fully-automated analysis of the Zoom Windows installer&lt;/a&gt;. It enumerates plenty of information about Zoom without access to its source code: reading unique machine information, anti-VM and anti-reverse-engineering tricks, reading config files, various types of network access, scanning mounted volumes, and more.&lt;/p&gt;
&lt;p&gt;To try this out yourself, use a sandbox designed for dynamic analysis. &lt;a href=&#34;https://github.com/cuckoosandbox&#34;&gt;Cuckoo&lt;/a&gt; is a common and easy-to-use solution, while &lt;a href=&#34;https://drakvuf.com/&#34;&gt;DRAKVUF&lt;/a&gt; is more advanced.&lt;/p&gt;
&lt;h3 id=&#34;extreme-example-the-truth-about-intel-me-and-amt&#34;&gt;Extreme example: the truth about Intel ME and AMT&lt;/h3&gt;
&lt;p&gt;The Intel Management Engine (ME) is a mandatory subsystem of all Intel processors (after 2008) with extremely privileged access to the host system. Active Management Technology (AMT) runs atop it on the subset of Intel processors with &amp;ldquo;vPro&amp;rdquo; branding. The latter can be disabled and is intended for organizations to remotely manage their inventory (installing software, monitoring, remote power-on/sleep/wake, etc).&lt;/p&gt;
&lt;p&gt;The fact that Intel ME has such deep access to the host system and the fact that it&amp;rsquo;s proprietary have both made it the subject of a high degree of scrutiny. Many people (most of whom have little experience in the area) connected these two facts together to allege that the ME is a backdoor, often by confusedly citing functionality of Intel AMT instead of ME. Is it really impossible to know for sure?&lt;/p&gt;
&lt;p&gt;I picked Intel ME+AMT to serve as an extreme example: it shows both the power and limitations of the analysis approaches covered. ME isn&amp;rsquo;t made of simple executables you can just run in an OS because it sits far below the OS, in what&amp;rsquo;s sometimes called &amp;ldquo;Ring -3&amp;rdquo;.&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt; Analysis is limited to external monitoring (e.g. by monitoring network activity) and reverse-engineering unpacked partially-obfuscated firmware updates, with help from official documentation. This is slower and harder than analyzing a typical executable or library.&lt;/p&gt;
&lt;p&gt;Answers are a bit complex and&amp;hellip;more boring than what sensationalized headlines would say. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://twitter.com/igorskochinsky&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Igor&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Skochinsky&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; (the developer of &lt;a href=&#34;https://github.com/skochinsky/me-tools&#34;&gt;me-tools&lt;/a&gt;) and &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://github.com/corna&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Nicola&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Corna&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; (the developer of &lt;a href=&#34;https://github.com/corna/me_cleaner&#34;&gt;me_cleaner&lt;/a&gt;) presented their analysis of ME in &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://fahrplan.events.ccc.de/congress/2017/Fahrplan/system/event_attachments/attachments/000/003/391/original/Intel_ME_myths_and_reality.pdf&#34;&gt;Intel Me: Myths and Reality&lt;/a&gt;&lt;/cite&gt; (&lt;span&gt;application/pdf&lt;/span&gt;)&lt;/span&gt;; &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Vassilios&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Ververis&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  thoroughly analyzed AMT in &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://kth.diva-portal.org/smash/get/diva2:508256/FULLTEXT01&#34;&gt;Security Evaluation of Intel&#39;s Active Management Technology&lt;/a&gt;&lt;/cite&gt; (&lt;time class=&#34;dt-published published&#34;&gt;2010&lt;/time&gt;, &lt;span&gt;application/pdf&lt;/span&gt;)&lt;/span&gt;. Interestingly, the former pair argues that auditing binary code is preferable to potentially misleading source code: binary analysis allows auditors to &amp;ldquo;cut the crap&amp;rdquo; and inspect what software is truly made of. However, this was balanced by a form of binary obfuscation that the pair encountered; I&amp;rsquo;ll describe it in a moment.&lt;/p&gt;
&lt;p&gt;Simply monitoring network activity and systematically testing all claims made by the documentation allowed Ververis to uncover a host of security issues in Intel AMT. However, no undocumented features have (to my knowledge) been uncovered. The problematic findings revolved around flawed/insecure implementations of documented functionality. In other words: there&amp;rsquo;s been no evidence of AMT being &amp;ldquo;a backdoor&amp;rdquo;, but its security flaws could have had a similar impact. Fortunately, AMT can be disabled. What about ME?&lt;/p&gt;
&lt;p&gt;This is where some binary analysis comes in. Neither Skochinsky&amp;rsquo;s &lt;a href=&#34;https://recon.cx/2014/slides/Recon%202014%20Skochinsky.pdf&#34;&gt;ME Secrets&lt;/a&gt; presentation nor &lt;cite&gt;Intel Me: Myths and Reality&lt;/cite&gt; seem to enumerate any contradictions with &lt;a href=&#34;https://link.springer.com/book/10.1007/978-1-4302-6572-6&#34;&gt;official Intel documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, some components are poorly understood due to being obfuscated using &lt;a href=&#34;https://io.netgarage.org/me/&#34;&gt;Huffman compression with unknown dictionaries&lt;/a&gt;. Understanding the inner workings of the obfuscated components blurs the line between software reverse-engineering and figuring out how the chips are actually made, the latter of which is nigh-impossible if you don&amp;rsquo;t have access to a chip lab full of cash. However, black-box analysis does tell us about the capabilities of these components: see page 21 of &amp;ldquo;ME Secrets&amp;rdquo;. Thanks to zdctg for clarifying this.&lt;/p&gt;
&lt;p&gt;Skochinsky&amp;rsquo;s and Corna&amp;rsquo;s analysis was sufficient to clarify (but not completely contradict) sensationalism claiming that ME can remotely lock any PC (it was a former opt-in feature), can spy on anything the user does (they clarified that access is limited to unblocked parts of the host memory and the integrated GPU, but doesn&amp;rsquo;t include e.g. the framebuffer), etc.&lt;/p&gt;
&lt;p&gt;While claims such as &amp;ldquo;ME is a black box that can do anything&amp;rdquo; are misleading, ME not without its share of vulnerabilities. My favorite look at its issues is a presentation by &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.blackhat.com/eu-17/speakers/Mark-Ermolov.html&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Mark&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Ermolov&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.blackhat.com/eu-17/speakers/Maxim-Goryachy.html&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Maxim&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Goryachy&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; at Black Hat Europe 2017: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.blackhat.com/docs/eu-17/materials/eu-17-Goryachy-How-To-Hack-A-Turned-Off-Computer-Or-Running-Unsigned-Code-In-Intel-Management-Engine-wp.pdf&#34;&gt;How to Hack a Turned-Off Computer, or Running Unsigned Code in Intel Management Engine&lt;/a&gt;&lt;/cite&gt; (&lt;span&gt;application/pdf&lt;/span&gt;)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In short: ME being proprietary doesn&amp;rsquo;t mean that we can&amp;rsquo;t find out how (in)secure it is. Binary analysis when paired with runtime inspection can give us a good understanding of what trade-offs we make by using it. While ME has a history of serious vulnerabilities, they&amp;rsquo;re nowhere near what &lt;a href=&#34;https://web.archive.org/web/20210302072839/themerkle.com/what-is-the-intel-management-engine-backdoor/&#34;&gt;borderline conspiracy theories&lt;/a&gt; claim.&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;(Note: Intel is not alone here. Other chips typically have equivalents, e.g. AMD Secure Technology).&lt;/p&gt;
&lt;h2 id=&#34;fuzzing&#34;&gt;Fuzzing&lt;/h2&gt;
&lt;p&gt;Manual invocation of a program paired with a tracer like &lt;code&gt;strace&lt;/code&gt; won&amp;rsquo;t always exercise all code paths or find edge-cases. &lt;a href=&#34;https://en.wikipedia.org/wiki/Fuzzing&#34;&gt;Fuzzing helps bridge this gap&lt;/a&gt;: it automates the process of causing a program to fail by generating random or malformed data to feed it. Researchers then study failures and failure-conditions to isolate a bug.&lt;/p&gt;
&lt;p&gt;Fuzzing doesn&amp;rsquo;t necessarily depend on access to source code, as it is a black-box technique. Fuzzers like &lt;a href=&#34;https://lcamtuf.coredump.cx/afl/&#34;&gt;American Fuzzy Loop (AFL)&lt;/a&gt; normally use &lt;a href=&#34;#special-builds&#34;&gt;special fuzz-friendly builds&lt;/a&gt;, but &lt;a href=&#34;https://aflplus.plus/docs/binaryonly_fuzzing/&#34;&gt;other fuzzing setups&lt;/a&gt; can work with just about any binaries. In fact, some types of fuzz tests (e.g. &lt;a href=&#34;https://github.com/KissPeter/APIFuzzer/&#34;&gt;fuzzing a web API&lt;/a&gt;) hardly need any implementation details.&lt;/p&gt;
&lt;p&gt;Fuzzing frequently catches bugs that are only apparent by running a program, not by reading source code. Even so, the biggest beneficiaries of fuzzing are open source projects. &lt;a href=&#34;https://github.com/curl/curl-fuzzer&#34;&gt;cURL&lt;/a&gt;, &lt;a href=&#34;https://github.com/openssl/openssl/tree/master/fuzz&#34;&gt;OpenSSL&lt;/a&gt;, web browsers, text rendering libraries (HarfBuzz, FreeType) and toolchains (GCC, Clang, the official Go toolchain, etc.) are some notable examples.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;I&amp;rsquo;ve said it before but let me say it again: fuzzing is really the top method to find problems in curl once we&amp;rsquo;ve fixed all flaws that the static analyzers we use have pointed out. The primary fuzzing for curl is done by OSS-Fuzz, that tirelessly keeps hammering on the most recent curl code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://daniel.haxx.se/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Daniel&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Stenberg&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://daniel.haxx.se/blog/2020/09/23/a-google-grant-for-libcurl-work/&#34;&gt;A Google grant for libcurl work&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If you want to get started with fuzzing, I recommend checking out &lt;a href=&#34;https://github.com/google/AFL/blob/master/docs/QuickStartGuide.txt&#34;&gt;the quick-start guide for American Fuzzy Loop&lt;/a&gt;. Some languages like Go 1.18 also have fuzzing tools available right in the standard library.&lt;/p&gt;
&lt;h3 id=&#34;example-cve-wbr-2022-0185&#34;&gt;Example: CVE-&lt;wbr /&gt;2022-0185&lt;/h3&gt;
&lt;p&gt;A recent example of how fuzzing helps spot a vulnerability in an open-source project is &lt;a href=&#34;https://www.openwall.com/lists/oss-security/2022/01/18/7&#34;&gt;CVE-&lt;wbr /&gt;2022-0185&lt;/a&gt;: a Linux 0-day found by the Crusaders of Rust a few weeks ago. It was discovered using the &lt;a href=&#34;https://github.com/google/syzkaller&#34;&gt;syzkaller&lt;/a&gt; kernel fuzzer. The process was documented on Will&amp;rsquo;s Root:&lt;/p&gt;
&lt;p class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;cite&gt;&lt;a class=&#34;u-url p-name&#34; href=&#34;https://www.willsroot.io/2022/01/cve-2022-0185.html&#34;&gt;CVE-&lt;wbr /&gt;2022-0185 - Winning a $31337 Bounty after Pwning Ubuntu and Escaping Google&#39;s KCTF Containers&lt;/a&gt;&lt;/cite&gt; by &lt;span
	
	class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://willsroot.io&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-nickname nickname&#34;&gt;willsroot&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;highly&lt;/em&gt; encourage giving it a read; it&amp;rsquo;s the perfect example of fuzzing with sanitizers to find a vulnerability, reproducing the vulnerability (by writing a tiny C program), &lt;em&gt;then&lt;/em&gt; diving into the source code to find and fix the cause, and finally reporting the issue (with a patch!). When source isn&amp;rsquo;t available, the vendor would assume responsibility for the &amp;ldquo;find and fix&amp;rdquo; steps.&lt;/p&gt;
&lt;p&gt;The fact that some of the most-used pieces of FLOSS in existence have been the biggest beneficiaries of source-agnostic approaches to vulnerability analysis should be quite revealing. The source code to these projects has received attention from millions of eyes, yet they &lt;em&gt;still&lt;/em&gt; invest in fuzzing infrastructure and vulnerability-hunters prefer analyzing artifacts over inspecting the source.&lt;/p&gt;
&lt;h2 id=&#34;good-counter-arguments&#34;&gt;Good counter-arguments&lt;/h2&gt;
&lt;p&gt;I readily concede to several points in favor of source availability from a security perspective:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Source code can make analysis &lt;em&gt;easier&lt;/em&gt; by &lt;em&gt;supplementing&lt;/em&gt; source-independent approaches. The lines between the steps I mentioned in the &lt;a href=&#34;#how-security-fixes-work&#34;&gt;four-step vulnerability-fixing process&lt;/a&gt; are blurry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Patching vulnerabilities is important. Source availability makes it possible for the community, package maintainers, or reporters of a vulnerability to patch software. Package maintainers often blur the line between &amp;ldquo;packager&amp;rdquo; and &amp;ldquo;contributor&amp;rdquo; by helping projects migrate away from abandoned/insecure dependencies. One example that comes to mind is the Python 2 to Python 3 transition for projects like Calibre.&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt; Being able to fix issues independent of upstream support is an important mitigation against &lt;a href=&#34;https://envs.net/~seirdy/2021/01/27/whatsapp-and-the-domestication-of-users/&#34;&gt;user domestication&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some developers/vendors don&amp;rsquo;t distribute binaries that make use of modern toolchain-level exploit mitigations (e.g. &lt;abbr title=&#34;Position-Independent Executables&#34;&gt;PIE&lt;/abbr&gt;, &lt;abbr title=&#34;ReLocation Read-Only&#34;&gt;RELRO&lt;/abbr&gt;, stack canaries, automatic variable initialization, &lt;a href=&#34;https://clang.llvm.org/docs/ControlFlowIntegrity.html&#34;&gt;&lt;abbr title=&#34;Control-Flow Integrity&#34;&gt;CFI&lt;/abbr&gt;&lt;/a&gt;, etc.&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;). In these cases, building software yourself with these mitigations (or delegating it to a distro that enforces them) requires source code availability (or at least some sort of intermediate representation).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Closed-source software may or may not have builds available that include sanitizers and debug symbols.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Although fuzzing release binaries is possible, fuzzing is much easier to do when source code is available. Vendors of proprietary software seldom release special fuzz-friendly builds, and filtering out false-positives can be quite tedious without understanding high-level design.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It is certainly possible to notice a vulnerability in source code. Excluding low-hanging fruit typically caught by static code analysis and peer review, it&amp;rsquo;s not the main way most vulnerabilities are found nowadays (thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://www.broken-by-design.fr/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-nickname nickname&#34;&gt;X_CLI&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for &lt;a href=&#34;https://lemmy.ml/post/167321/comment/117774&#34;&gt;reminding me about what source analysis does accomplish&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Software as a Service can be incredibly difficult to analyze, as we typically have little more than the ability to query a server. Servers don&amp;rsquo;t send core dumps, server-side binaries, or trace logs for analysis. Furthermore, it&amp;rsquo;s difficult to verify which software a server is running.&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt; For services that require trusting a server, access to the server-side software is important from both a security and a user-freedom perspective&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of this post is written with the assumption that binaries are inspectable and traceable. Binary obfuscation and some forms of content protection/&lt;abbr title=&#34;Digital Rights Management&#34;&gt;DRM&lt;/abbr&gt; violate this assumption and actually do make analysis more difficult.&lt;/p&gt;
&lt;p&gt;Beyond source code, transparency into the development helps assure users of compliance with good security practices. Viewing VCS history, patch reviews, linter configurations, etc. reveal the standards that code is being held up to, some of which can be related to bug-squashing and security.&lt;/p&gt;
&lt;p&gt;&lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://matrix.to/#/@hypokeimenon:tchncs.de&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-nickname nickname&#34;&gt;Patience&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; on Matrix also had a great response, which I agree with and adapt below:&lt;/p&gt;
&lt;p&gt;Whether or not the source code is available for software does not change how insecure it is. However, there are good security-related incentives to publish source code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Doing so improves vulnerability patchability and future architectural improvement by lowering the barrier to contribution. The fixes that follow can be &lt;em&gt;shared and used by other projects&lt;/em&gt; across the field, some of which can in turn be used by the vendor. This isn&amp;rsquo;t a zero-sum game; a rising tide lifts all boats.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s generally good practice to assume an attacker has full knowledge of a system instead of relying on security through obscurity. Releasing code provides strong assurance that this assumption is being made. It&amp;rsquo;s a way for vendors to put their money where their mouth is.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both Patience and &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://drewdevault.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Drew&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Devault&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; argue that given the above points, a project whose goal is maximum security would release code. Strictly speaking, I agree. Good intentions don&amp;rsquo;t imply good results, but they can &lt;em&gt;supplement&lt;/em&gt; good results to provide some trust in a project&amp;rsquo;s future.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve gone over some examples of how analyzing a software&amp;rsquo;s security properties need not depend on source code, and vulnerability discovery in both FLOSS and in proprietary software uses source-agnostic techniques. Dynamic and static black-box techniques are powerful tools that work well from user-space (Zoom) to kernel-space (Linux) to low-level components like Intel ME+AMT. Source code enables the vulnerability-fixing process but has limited utility for the evaluation/discovery process.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t assume software is safer than proprietary alternatives just because its source is visible; come to a conclusion after analyzing both. There are lots of great reasons to switch from macOS or Windows to Linux (it&amp;rsquo;s been my main OS for years), but &lt;a href=&#34;https://madaidans-insecurities.github.io/linux.html&#34;&gt;security is low on that list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All other things being mostly equal, FLOSS is obviously &lt;em&gt;preferable&lt;/em&gt; from a security perspective; I listed some reasons why in the counter-arguments section. Unfortunately, being helpful is not the same as being necessary. All I argue is that source unavailability does not imply insecurity, and source availability does not imply security. Analysis approaches that don&amp;rsquo;t rely on source are typically the most powerful, and can be applied to both source-available and source-unavailable software. Plenty of proprietary software is more secure than FLOSS alternatives; few would argue that the sandboxing employed by Google Chrome or Microsoft Edge is more vulnerable than Pale Moon or most WebKitGTK-based browsers, for instance.&lt;/p&gt;
&lt;p&gt;Releasing source code is just one thing vendors can do to improve audits; other options include releasing test builds with debug symbols/sanitizers, publishing docs describing their architecture, and/or just keeping software small and simple. We should evaluate software security through &lt;em&gt;study&lt;/em&gt; rather than source model. Support the right things for the right reasons, and help others make informed choices with accurate information. There are enough good reasons to support software freedom; we don&amp;rsquo;t need to rely on bad ones.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Writing an alternative or re-implementation doesn&amp;rsquo;t require access to the original&amp;rsquo;s source code, as is evidenced by a plethora of clean-room re-implementations of existing software written to circumvent the need to comply with license terms.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Ideally well-documented, non-obfuscated code.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Or a JIT compiler, or a &lt;a href=&#34;https://en.wikipedia.org/wiki/Analytical_Engine&#34;&gt;bunch of clockwork&lt;/a&gt;, or&amp;hellip;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;For completeness, I should add that there is one source-based approach that can verify correctness: formal proofs. Functional programming languages that &lt;a href=&#34;https://en.wikipedia.org/wiki/Dependent_type&#34;&gt;support dependent types&lt;/a&gt; can be provably correct at the source level. Assuming their self-hosted toolchains have similar guarantees, developers using these languages might have to worry less about bugs they couldn&amp;rsquo;t find in the source code. This can alleviate concerns that their language runtimes can make it hard to reason about low-level behavior. Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://adrian.geek.nz/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Adrian&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Cochrane&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for pointing this out.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;For example: C, C++, Objective-C, Go, Fortran, and others can utilize sanitizers from Clang and/or GCC.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;This is probably what people in &lt;em&gt;The Matrix&lt;/em&gt; were using to see that iconic &lt;a href=&#34;https://en.wikipedia.org/wiki/Matrix_digital_rain&#34;&gt;digital rain&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;This command only lists syscall names, but I did eventually follow the example of &lt;a href=&#34;https://github.com/Whonix/sandbox-app-launcher&#34;&gt;sandbox-app-launcher&lt;/a&gt; by allowing certain syscalls (e.g. ioctl) only when invoked with certain parameters. Also, I used &lt;a href=&#34;https://github.com/BurntSushi/ripgrep&#34;&gt;ripgrep&lt;/a&gt; because I&amp;rsquo;m more familiar with &lt;abbr title=&#34;Perl-Compatible Regular Expressions&#34;&gt;PCRE&lt;/abbr&gt;-style capture groups.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Decrypting these packets typically involves saving and using key logs, or using endpoints with &lt;a href=&#34;https://blog.didierstevens.com/2020/12/14/decrypting-tls-streams-with-wireshark-part-1/&#34;&gt;known pre-master secrets&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;I invite any modders who miss these debug symbols to check out the FLOSS &lt;a href=&#34;https://www.minetest.net/&#34;&gt;Minetest&lt;/a&gt;, perhaps with the &lt;a href=&#34;https://content.minetest.net/packages/Wuzzy/mineclone2/&#34;&gt;MineClone2&lt;/a&gt; game.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;See page 127-130 of the Invisible Things Lab&amp;rsquo;s &lt;a href=&#34;https://invisiblethingslab.com/resources/misc09/Quest%20To%20The%20Core%20%28public%29.pdf&#34;&gt;Quest to the Core slides&lt;/a&gt;. Bear in mind that they often refer to AMT running atop ME.&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;As an aside: your security isn&amp;rsquo;t necessarily improved by &amp;ldquo;disabling&amp;rdquo; it, since it still runs during the initial boot sequence and does provide some hardening measures of its own (e.g., a &lt;abbr title=&#34;Trusted Platform Module&#34;&gt;TPM&lt;/abbr&gt;).&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;In 2017, Calibre&amp;rsquo;s author actually wanted to stay with Python 2 after its EOL date, and &lt;a href=&#34;https://bugs.launchpad.net/calibre/&amp;#43;bug/1714107&#34;&gt;maintain Python 2 himself&lt;/a&gt;. Users and package maintainers were quite unhappy with this, as Python 2 would no longer be receiving security fixes after 2020. While official releases of Calibre use a bundled Python interpreter, distro packages typically use the system Python package; Calibre&amp;rsquo;s popularity and insistence on using Python 2 made it a roadblock to getting rid of the Python 2 package in most distros. What eventually happened was that community members (especially &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://github.com/eli-schwartz&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Eli&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Schwartz&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://flaviutamas.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Flaviu&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Tamas&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;) submitted patches to migrate Calibre away from Python 2. Calibre migrated to Python 3 by &lt;a href=&#34;https://calibre-ebook.com/new-in/fourteen&#34;&gt;version 5.0&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;Linux distributions&amp;rsquo; CFI+&lt;abbr title=&#34;Adress-Space Layout Randomization&#34;&gt;ASLR&lt;/abbr&gt; implementations rely executables compiled with CFI+PIE support, and ideally with stack-smashing protectors and no-execute bits. These implementations are flawed (see &lt;a href=&#34;https://web.archive.org/web/20211021222659/http://cybersecurity.upv.es/attacks/offset2lib/offset2lib-paper.pdf&#34;&gt;On the Effectiveness of Full-ASLR on 64-bit Linux&lt;/a&gt; and &lt;a href=&#34;https://grsecurity.net/PaX-presentation.pdf&#34;&gt;Brad Spengler&amp;rsquo;s presentation comparing these with PaX&amp;rsquo;s own implementation&lt;/a&gt;).&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;The &lt;a href=&#34;https://signal.org/blog/private-contact-discovery/&#34;&gt;best attempt I know of&lt;/a&gt; leverages &lt;a href=&#34;https://en.wikipedia.org/wiki/Trusted_execution_environment&#34;&gt;Trusted Execution Environments&lt;/a&gt;, but for limited functionality using an implementation that&amp;rsquo;s &lt;a href=&#34;https://en.wikipedia.org/wiki/Software_Guard_Extensions#Attacks&#34;&gt;far from bulletproof&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Misinfo about Permissions Policy and FLoC</title>
      <link>https://envs.net/~seirdy/posts/2021/04/16/permissions-policy-floc-misinfo/</link>
      <pubDate>Sat, 17 Apr 2021 00:28:06 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2021/04/16/permissions-policy-floc-misinfo/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2021/04/16/permissions-policy-floc-misinfo/">&lt;p&gt;&lt;em&gt;Update: I&amp;rsquo;ve amended this post with a valid reason to use the header. More info at the bottom.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This post was &lt;a href=&#34;https://www.goodreads.com/quotes/219878-a-lie-can-run-round-the-world-before-the-truth&#34;&gt;written in a hurry&lt;/a&gt; in response to some misinformation about Google&amp;rsquo;s newest Web antifeature, Federated Learning of Cohorts (FLoC). Google&amp;rsquo;s FLoC is an attempt to track users even when their browsers (rightly) block third-party cookies. The initial blog posts about this issue were quite benign, but online discussions quickly devolved into panic and support for building flawed work-arounds into upstream software. I had to write this before things got out of hand.&lt;/p&gt;
&lt;p&gt;A lot of misleading online discussion stems from one not-very-misleading &lt;a href=&#34;https://paramdeo.com/blog/opting-your-website-out-of-googles-floc-network&#34;&gt;blog post&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; that&amp;rsquo;s been making rounds, instructing webmasters everywhere to add the following HTTP response headers to all their pages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Permissions-Policy: interest-cohort=()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Strictly speaking, this advice is correct; including this header will prevent your page form using Google&amp;rsquo;s FLoC. What the advice misses is that the header isn&amp;rsquo;t always necessary and isn&amp;rsquo;t even the ideal way to prevent your page from doing nefarious things.&lt;/p&gt;
&lt;p&gt;That advice comes from a &lt;a href=&#34;https://plausible.io/blog/google-floc#how-to-opt-out-of-floc-as-a-web-developer-set-a-permissions-policy&#34;&gt;post by Plausible Analytics&lt;/a&gt;; the author of that post concluded that FLoC is an &amp;ldquo;opt-out&amp;rdquo; antifeature by reading the &lt;a href=&#34;https://github.com/WICG/floc#opting-out-of-computation&#34;&gt;&amp;ldquo;Opting Out of Computation&amp;rdquo; section&lt;/a&gt; of the WICG&amp;rsquo;s FLoC README.&lt;/p&gt;
&lt;p&gt;If you check that README yourself, you&amp;rsquo;ll notice the following statement one (1) paragraph above the mention of the HTTP permission policy (emphasis mine):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A site should be able to declare that it does not want to be included in the user&amp;rsquo;s list of sites for cohort calculation. This can be accomplished via a new &lt;code&gt;interest-cohort&lt;/code&gt; &lt;a href=&#34;https://www.w3.org/TR/permissions-policy-1/&#34;&gt;permissions policy&lt;/a&gt;. This policy will be default allow. Any frame that is not allowed &lt;code&gt;interest-cohort&lt;/code&gt; permission will have a default value returned &lt;strong&gt;when they call &lt;code&gt;document.interestCohort()&lt;/code&gt;.&lt;/strong&gt; If the main frame does not have &lt;code&gt;interest-cohort&lt;/code&gt; permission then the page visit will not be included in interest cohort calculation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If your website does not include JS that calls &lt;code&gt;document.interestCohort()&lt;/code&gt;, it will not leverage Google&amp;rsquo;s FLoC. Explicitly opting out will not change this.&lt;/p&gt;
&lt;p&gt;As per a &lt;a href=&#34;https://web.dev/floc/&#34;&gt;post&lt;/a&gt; on Google&amp;rsquo;s web development blog, web.dev, FLoC also will be enabled during an origin trial if the page &amp;ldquo;loads ads or ads-related resource&amp;rdquo;; i.e., anything that Chromium&amp;rsquo;s &lt;a href=&#34;https://chromium.googlesource.com/chromium/src/&amp;#43;/master/docs/ad_tagging.md&#34;&gt;ad tagger&lt;/a&gt; classifies as an ad. If your website loads third-party ads, it might end up getting opted-in even if those ads don&amp;rsquo;t call &lt;code&gt;document.interestCohort()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;what-explicitly-opting-out-actually-entails&#34;&gt;What explicitly opting out actually entails&lt;/h2&gt;
&lt;p&gt;What adding this header does is exclude your website from being used when calcualting a user&amp;rsquo;s cohort. A cohort is an identifier shared with a few thousand other users, calculated locally from browsing history; sites that send this header will be excluded from this calculation. The EFF estimates that a cohort ID can add up to 8 bits of of entropy to a user&amp;rsquo;s fingerprint.&lt;/p&gt;
&lt;p&gt;Being excluded from cohort calculation has a chance to place a user in a different cohort, altering a user&amp;rsquo;s fingerprint. This new fingerprint may or may not have more entropy than the one derived without being excluded. Excluding some portion of sites from a user&amp;rsquo;s cohort calculation doesn&amp;rsquo;t necessarily make a user less unique if a nontrivial number of sites doesn&amp;rsquo;t opt out.&lt;/p&gt;
&lt;p&gt;Given this marginal improvement, I don&amp;rsquo;t think it&amp;rsquo;s right to place a burden or blame on webmasters when the burden and blame should rightfully be directed at those responsible for rolling this antifeature out in Chromium. We shouldn&amp;rsquo;t expect webmasters to add a tag or header every time Google advances the war against its own users.&lt;/p&gt;
&lt;h2 id=&#34;how-permissions-policy-works&#34;&gt;How Permissions Policy works&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t think that every webmaster should have to read every single W3C spec. I do, however, think that people who offer prescriptive advice and interpretations of a spec should be expected to read the relevant spec first.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s &lt;a href=&#34;https://www.w3.org/TR/permissions-policy-1/&#34;&gt;a copy&lt;/a&gt; of the Permissions Policy spec. Essentially, the &lt;code&gt;Permissions-Policy&lt;/code&gt; header allows a webmaster to whitelist which parties (if any) are allowed to leverage certain APIs. If I make a website that doesn&amp;rsquo;t perform any geolocation directly but I load a third-party widget that does, I can forbid all parties from using Geolocation APIs by setting the following Permissions-Policy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Permissions-Policy: geolocation=()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other words, it provides a global override for any page contents requesting too many permissions. It&amp;rsquo;s ideal for situations in which authors aren&amp;rsquo;t in control of what content is being loaded.&lt;/p&gt;
&lt;p&gt;Using the Permissions Policy to opt out of cohort calculation isn&amp;rsquo;t really what the Permissions Policy was intended for. That doesn&amp;rsquo;t seem like a big deal until you consider the history of HTTP headers being used to protect privacy.&lt;/p&gt;
&lt;h2 id=&#34;this-has-happened-before&#34;&gt;This has happened before&lt;/h2&gt;
&lt;p&gt;Google&amp;rsquo;s non-standard usage of the Permissions Policy header to opt a site out of cohort calculation is reminiscent of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Do_Not_Track&#34;&gt;Do Not Track (DNT) header&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Do Not Track was a non-standard client header used to request websites not to track users. This ended up getting ignored by almost all sites it was intended to target, as adtech companies had no incentive to comply. Several websites initially obeyed the header until eventually dropping support; Reddit is a notable recent example.&lt;/p&gt;
&lt;p&gt;Given that non-standard header usage has failed in the client-side fight against surveillance capitalism before, I&amp;rsquo;m not too optimistic about trying this again from the server side.&lt;/p&gt;
&lt;h2 id=&#34;better-advice-how-not-to-opt-in&#34;&gt;Better advice: how not to opt-in&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s how not to opt-in to Google&amp;rsquo;s FLoC:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t load untrusted third-party content that might get classified as an ad (only applies during the origin trial)&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t call &lt;code&gt;document.interestCohort()&lt;/code&gt;, and don&amp;rsquo;t load third-party scripts that might call it either.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have to resort to adding a &lt;code&gt;Permissions-Policy&lt;/code&gt; header to opt your site out of FLoC, it means that you&amp;rsquo;ve accidentally opted yourself in by including a tracking script (malware) on your page. I&amp;rsquo;d wager that opting into FLoC wasn&amp;rsquo;t the only nefarious thing those scripts do; chances are they bundle a host of other fingerprinting measures.&lt;/p&gt;
&lt;p&gt;To be extra safe, you can whitelist exactly what scripts can run with a &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP&#34;&gt;Content Security Policy&lt;/a&gt; (CSP); seirdy.one, for instance, has a CSP that blocks all scripts, forms, frames, and third-party resources from loading.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re concerned about Google breaking the spec and opting you in even after you&amp;rsquo;ve not done so yourself, what reason do you have to believe that they&amp;rsquo;ll stop there? There&amp;rsquo;s nothing preventing Google from ignoring your &lt;code&gt;Permissions-Policy&lt;/code&gt; header, either.&lt;/p&gt;
&lt;h2 id=&#34;take-a-breath&#34;&gt;Take a breath&lt;/h2&gt;
&lt;p&gt;If you want to be extra safe, you&amp;rsquo;re free to add this header to your site. Just manage your expectations. However:&lt;/p&gt;
&lt;p&gt;Please, don&amp;rsquo;t spam maintainers of web server/backend software to tell them to include this header by default when it may or may not actually reduce user fingerprints. Don&amp;rsquo;t tell webmasters that they have a &lt;em&gt;moral obligation&lt;/em&gt; to add a Permissions Policy header either.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; You don&amp;rsquo;t need to add this permission policy to every request, just as you don&amp;rsquo;t need to wear a helmet for every form of physical activity. Knee-jerk reactions like patching upstream software only galvanize Google to start ignoring this non-standard usage of the Permissions Policy header.&lt;/p&gt;
&lt;h2 id=&#34;update-a-valid-reason-to-add-this-header&#34;&gt;Update: a valid reason to add this header&lt;/h2&gt;
&lt;p&gt;Some IRC discussions and a Hacker News commenter have helped me understand a valid reason to add a &lt;code&gt;Permissions-Policy&lt;/code&gt; header: making a statement. Opting your site out of FLoC might not significantly improve user privacy, but it does send a clear message that you&amp;rsquo;re against it.&lt;/p&gt;
&lt;p&gt;I was initially skeptical of this justification for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Google is unlikely to care if most of the non-adtech Web disabled FLoC, since they aren&amp;rsquo;t Google&amp;rsquo;s customers. If you work at Google, feel free to prove me wrong.&lt;/li&gt;
&lt;li&gt;Most websites won&amp;rsquo;t include the header, so it&amp;rsquo;s unlikely to make a big difference.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, I&amp;rsquo;ve changed my mind for one reason: if enough people implement this header, then anyone looking at HTTP headers will be reminded of the existence of FLoC. Making a statement like this will help spread awareness. I do maintain that effort is better spent getting users off Chromium and Chromium-dependent browsers, though.&lt;/p&gt;
&lt;p&gt;Normally, I&amp;rsquo;d be against making a statement in response header fields; messages meant to be parsed by humans should be sent in the body instead. I&amp;rsquo;m making an exception because &lt;code&gt;interest-cohort&lt;/code&gt; will likely become an official addition to the Permissions-Policy standard.&lt;/p&gt;
&lt;p&gt;In short: FLoC is a terrible idea partly because &amp;ldquo;opting out&amp;rdquo; your site won&amp;rsquo;t significantly improve users&amp;rsquo; privacy. Opt out of FLoC with the suggested header if you want to make a statement, not because you think you think you&amp;rsquo;re fulfilling your moral obligation to protect your visitors. If you want to fulfill that obligation, &lt;strong&gt;get them off of Chrome and Google.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;This isn&amp;rsquo;t the only post making rounds, but it did hit the front page of a certain orange-colored website. I&amp;rsquo;m not blaming the author; if I hadn&amp;rsquo;t encountered the Permissions Policy spec earlier, I probably would have also taken the advice the author read at face-value.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I&amp;rsquo;ve noticed both of these behaviors on several threads online. I&amp;rsquo;ve decided against linking to them because I think the discourse there has heated past the point of reason.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>A look at search engines with their own indexes</title>
      <link>https://envs.net/~seirdy/posts/2021/03/10/search-engines-with-own-indexes/</link>
      <pubDate>Wed, 10 Mar 2021 20:51:06 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2021/03/10/search-engines-with-own-indexes/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2021/03/10/search-engines-with-own-indexes/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2 id=&#34;preface&#34;&gt;Preface&lt;/h2&gt;
&lt;p&gt;This is a cursory review of all the indexing search engines I have been able to find.&lt;/p&gt;
&lt;p&gt;The three dominant English search engines with their own indexes&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; are Google, Bing, and Yandex (&lt;abbr title=&#34;Google, Bing, Yandex&#34;&gt;GBY&lt;/abbr&gt;). Many alternatives to GBY exist, but almost none of them have their own results; instead, they just source their results from GBY.&lt;/p&gt;
&lt;p&gt;With that in mind, I decided to test and catalog all the different indexing search engines I could find. I prioritized breadth over depth, and encourage readers to try the engines out themselves if they&amp;rsquo;d like more information.&lt;/p&gt;
&lt;p&gt;This page is a &amp;ldquo;living document&amp;rdquo; that I plan on updating indefinitely. Check for updates once in a while if you find this page interesting. Feel free to send me suggestions, updates, and corrections; I&amp;rsquo;d especially appreciate help from those who speak languages besides English and can evaluate a non-English indexing search engine. Contact info is in the article footer.&lt;/p&gt;
&lt;p&gt;I plan on updating the engines in the top two categories with more info comparing the structured/linked data the engines leverage (RDFa vocabularies, microdata, microformats, JSON-LD, etc.) to help authors determine which formats to use.&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#about-the-list&#34;&gt;About the list&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#general-indexing-search-engines&#34;&gt;General indexing search-engines&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#large-indexes-good-results&#34;&gt;Large indexes, good results&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#smaller-indexes-or-less-relevant-results&#34;&gt;Smaller indexes or less relevant results&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#smaller-indexes-hit-and-miss&#34;&gt;Smaller indexes, hit-and-&lt;wbr /&gt;miss&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#fledgling-engines&#34;&gt;Fledgling engines&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#semi-independent-indexes&#34;&gt;Semi-independent indexes&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#non-generalist-search&#34;&gt;Non-generalist search&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#small-or-non-commercial-web&#34;&gt;Small or non-commercial Web&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#site-finders&#34;&gt;Site finders&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#other&#34;&gt;Other&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#other-languages&#34;&gt;Other languages&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#big-indexes&#34;&gt;Big indexes&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#smaller-indexes&#34;&gt;Smaller indexes&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#almost-qualified&#34;&gt;Almost qualified&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#misc&#34;&gt;Misc&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#search-engines-without-a-web-interface&#34;&gt;Search engines without a web interface&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#graveyard&#34;&gt;Graveyard&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#upcoming-engines&#34;&gt;Upcoming engines&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#exclusions&#34;&gt;Exclusions&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#rationale&#34;&gt;Rationale&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#conflicts-of-interest&#34;&gt;Conflicts of interest&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#information-diversity&#34;&gt;Information diversity&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#methodology&#34;&gt;Method­ology&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#discovery&#34;&gt;Discovery&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#criteria-for-inclusion&#34;&gt;Criteria for inclusion&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#evaluation&#34;&gt;Evaluation&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#unique-results-without-unique-indexes&#34;&gt;Unique results without unique indexes&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#caveats&#34;&gt;Caveats&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#findings&#34;&gt;Findings&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#acknowledgements&#34;&gt;Acknow­ledgements&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;h2 id=&#34;about-the-list&#34;&gt;About the list&lt;/h2&gt;
&lt;p&gt;I discuss my motivation for making this page in the &lt;a href=&#34;#rationale&#34;&gt;Rationale section&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I primarily evaluated English-speaking search engines because that’s my primary language. With some difficulty, I could probably evaluate a Spanish one; however, I wasn&amp;rsquo;t able to find many Spanish-language engines powered by their own crawlers.&lt;/p&gt;
&lt;p&gt;I mention details like &amp;ldquo;allows site submissions&amp;rdquo; and structured data support where I can only to inform authors about their options, not as points in engines&amp;rsquo; favor.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;#methodology&#34;&gt;Methodology section&lt;/a&gt; at the bottom to learn how I evaluated each one.&lt;/p&gt;
&lt;h2 id=&#34;general-indexing-search-engines&#34;&gt;General indexing search-engines&lt;/h2&gt;
&lt;h3 id=&#34;large-indexes-good-results&#34;&gt;Large indexes, good results&lt;/h3&gt;
&lt;p&gt;These are large engines that pass all my standard tests and more.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Google&lt;/dt&gt;
&lt;dd&gt;The biggest index. Allows submitting pages and sitemaps for crawling, and &lt;a href=&#34;https://developers.google.com/search/docs/advanced/sitemaps/build-sitemap#addsitemap&#34;&gt;even supports WebSub&lt;/a&gt; to automate the process. Powers a few other engines:
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A former version of &lt;a href=&#34;https://www.startpage.com/&#34;&gt;Startpage&lt;/a&gt;, possibly the most popular Google proxy. Startpage now uses Bing&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://search.gmx.com/web&#34;&gt;GMX Search&lt;/a&gt;, run by a popular German email provider.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(discontinued) Runnaroo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://leta.mullvad.net/faq&#34;&gt;Mullvad Leta&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.sapo.pt/&#34;&gt;SAPO&lt;/a&gt; (Portuguese interface, can work with English results)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.dsearch.com/&#34;&gt;DSearch&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.13tabs.com/&#34;&gt;13TABS&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://zarebin.ir/&#34;&gt;Zarebin&lt;/a&gt; (Persian, can return English results)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ecosia (choose between Google and Bing providers in settings)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A host of other engines using &lt;a href=&#34;https://developers.google.com/custom-search/&#34;&gt;Programmable Search Engine&amp;rsquo;s&lt;/a&gt; client-side scripts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Bing&lt;/dt&gt;
&lt;dd&gt;The runner-up. Allows submitting pages and sitemaps for crawling without login using &lt;a href=&#34;https://www.indexnow.org/&#34;&gt;the IndexNow API&lt;/a&gt;, sharing IndexNow page submissions with Yandex and Seznam. Its index powers many other engines:
&lt;ul&gt;
&lt;li&gt;Yahoo (and its sibling engine, One­Search)&lt;/li&gt;
&lt;li&gt;DuckDuck­Go&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; (offers a Tor onion service, a JS-free version, and a TUI-browser-friendly &amp;ldquo;lite&amp;rdquo; version making it a good way to use Bing anonymously)&lt;/li&gt;
&lt;li&gt;AOL&lt;/li&gt;
&lt;li&gt;Qwant (partial)&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Ecosia (choose between Google and Bing providers in settings)&lt;/li&gt;
&lt;li&gt;Ekoru&lt;/li&gt;
&lt;li&gt;Privado&lt;/li&gt;
&lt;li&gt;Findx&lt;/li&gt;
&lt;li&gt;Disconnect Search&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;PrivacyWall&lt;/li&gt;
&lt;li&gt;Lilo&lt;/li&gt;
&lt;li&gt;Search­Scene&lt;/li&gt;
&lt;li&gt;Peekier (not to be confused with Peekr, a metasearch engine with its own index)&lt;/li&gt;
&lt;li&gt;Oscobo&lt;/li&gt;
&lt;li&gt;Million Short&lt;/li&gt;
&lt;li&gt;Yippy search&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Lycos&lt;/li&gt;
&lt;li&gt;Givero&lt;/li&gt;
&lt;li&gt;Swisscows&lt;/li&gt;
&lt;li&gt;Fireball&lt;/li&gt;
&lt;li&gt;Netzzappen&lt;/li&gt;
&lt;li&gt;You.com&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Vuhuv&lt;/li&gt;
&lt;li&gt;Partially powers MetaGer by default; this can be turned off&lt;/li&gt;
&lt;li&gt;ChatGPT Search&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;At this point, I mostly stopped adding Bing-&lt;wbr /&gt;based search engines. There are just too many.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Yandex&lt;/dt&gt;
&lt;dd&gt;Originally a Russian search engine, it now has an English version. Some Russian results bleed into its English site. It allows submitting pages and sitemaps for crawling using the IndexNow API, sharing IndexNow page submissions with Bing and Seznam. Powers:
&lt;ul&gt;
&lt;li&gt;Epic Search (went paid-only as of June 2021)&lt;/li&gt;
&lt;li&gt;Occasionally powers DuckDuck­Go&amp;rsquo;s link results instead of Bing &lt;ins cite=&#34;https://energycommerce.house.gov/committee-activity/hearings/hearing-on-holding-big-tech-accountable-legislation-to-protect-online&#34;&gt;(update: DuckDuckGo has &amp;ldquo;paused&amp;rdquo; its partnership with Yandex, confirmed in &lt;cite&gt;&lt;a href=&#34;https://energycommerce.house.gov/committee-activity/hearings/hearing-on-holding-big-tech-accountable-legislation-to-protect-online&#34;&gt;Hearing on “Holding Big Tech Accountable: Legislation to Protect Online Users”&lt;/a&gt;&lt;/cite&gt;&lt;/ins&gt;&lt;/li&gt;
&lt;li&gt;Petal, for Russian users only.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.mojeek.com/&#34;&gt;Mojeek&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Seems privacy-oriented with a large index containing billions of pages. Quality isn&amp;rsquo;t at GBY&amp;rsquo;s level, but it’s not bad either. If I had to use Mojeek as my default general search engine, I&amp;rsquo;d live. Partially powers &lt;a href=&#34;https://www.etools.ch/&#34;&gt;eTools.ch&lt;/a&gt;. At this moment, &lt;em&gt;I think that Mojeek is the best alternative to GBY&lt;/em&gt; for general search.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Google, Bing, and Yandex support structured data such as microformats1, microdata, RDFa, Open Graph markup, and JSON-LD. Yandex&amp;rsquo;s support for microformats1 is limited; for instance, it can parse &lt;code&gt;h-card&lt;/code&gt; metadata for organizations but not people. Open Graph and Schema.org are the only supported vocabularies I&amp;rsquo;m aware of. Mojeek is evaluating structured data; it&amp;rsquo;s interested in Open Graph and Schema.org vocabularies.&lt;/p&gt;
&lt;h3 id=&#34;smaller-indexes-or-less-relevant-results&#34;&gt;Smaller indexes or less relevant results&lt;/h3&gt;
&lt;p&gt;These engines pass most of the tests listed in the &amp;ldquo;methodology&amp;rdquo; section. All of them seem relatively privacy-friendly. I wouldn&amp;rsquo;t recommend using these engines to find specific answers; they&amp;rsquo;re better for learning about a topic by finding interesting pages related to a set of keywords.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://trystract.com/&#34;&gt;Stract&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;strong&gt;My favorite generalist engine on this page.&lt;/strong&gt; Stract supports advanced ranking customization by allowing users to import &amp;ldquo;optics&amp;rdquo; files, like a better version of Brave&amp;rsquo;s &amp;ldquo;goggles&amp;rdquo; feature. &lt;a href=&#34;https://github.com/StractOrg/stract&#34;&gt;Stract is fully open-source&lt;/a&gt;, with code released under an AGPL-3.0 license. The index is isn&amp;rsquo;t massive but it&amp;rsquo;s big enough to be a useful supplement to more major engines. Stract started with the Common Crawl index, but now uses its own crawler. Plans to add contextual ads and a subscription option for ad-free search. Discovered in my access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://rightdao.com&#34;&gt;Right Dao&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Very fast, good results. Passes the tests fairly well. It plans on including query-based ads if/when its user base grows.&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; For the past few months, its index seems to have focused more on large, established sites rather than smaller, independent ones. It seems to be a bit lacking in more recent pages.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.alexandria.org/&#34;&gt;Alexandria&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A pretty new &amp;ldquo;non-profit, ad free&amp;rdquo; engine, with &lt;a href=&#34;https://github.com/alexandria-org/alexandria&#34;&gt;freely-licensed code&lt;/a&gt;. Surprisingly good at finding recent pages. Its index is built from the Common Crawl; it isn&amp;rsquo;t as big as Gigablast or Right Dao but its ranking is great.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://yep.com/&#34;&gt;Yep&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;An ambitious engine from Ahrefs, an SEO/backlink-finder company, that &amp;ldquo;shares ad profit with creators and protects your privacy&amp;rdquo;. Most engines show results that include keywords from or related to the query; Yep also shows results linked by pages containing the query. In other words, not all results contain relevant keywords. This makes it excellent for less precise searches and discovery of &amp;ldquo;related sites&amp;rdquo;, especially with its index of &lt;em&gt;hundreds of billions of pages.&lt;/em&gt; It&amp;rsquo;s far worse at finding very specific information or recent events for now, but it will probably improve. It was known as &amp;ldquo;FairSearch&amp;rdquo; before its official launch.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://sese.yyj.moe/&#34;&gt;SeSe Engine&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Although it&amp;rsquo;s a Chinese engine, its index seems to have a large-enough proportion of English content to fit here. The engine is open-source; see the &lt;a href=&#34;https://github.com/RimoChan/sese-engine&#34;&gt;SeSe back-end Python code&lt;/a&gt; and &lt;a href=&#34;https://github.com/YunYouJun/sese-engine-ui&#34;&gt;the SeSe-ui Vue-based front-end&lt;/a&gt;. It has surprisingly good results for such a low-budget project. Each result is annotated with detailed ranking metadata such as keyword relevance and backlink weight. Discovered in my access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://greppr.org/&#34;&gt;greppr&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Its tagline is &amp;ldquo;Search the Internet with no filters, no tracking, no ads.&amp;rdquo; At the time of writing, it has over 3 million pages indexed. It&amp;rsquo;s surprisingly good at finding interesting new results for broad short-tail queries, if you&amp;rsquo;re willing to scroll far enough down the page. It appears to be good at finding recent pages.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Yep supports Open Graph and some JSON-LD at the moment. A look through the source code for Alexandria and Gigablast didn&amp;rsquo;t seem to reveal the use of any structured data. The surprising quality of results from SeSe and Right Dao seems influenced by the crawlers&amp;rsquo; high-quality starting location: Wikipedia.&lt;/p&gt;
&lt;h3 id=&#34;smaller-indexes-hit-and-miss&#34;&gt;Smaller indexes, hit-and-&lt;wbr /&gt;miss&lt;/h3&gt;
&lt;p&gt;These engines fail badly at a few important tests. Otherwise, they seem to work well enough for users who&amp;rsquo;d like some more serendipity in less-specific searches.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://peekr.org/&#34;&gt;Peekr (formerly SvMetaSearch, not to be confused with Peekier)&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Originally a SearxNG metasearch engine that also included results from its own index, it&amp;rsquo;s since diverged. It now appears to return all results from its own growing ElasticSearch index. Open source, with an emphasis on self-hostability.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;http://www.seekport.com/&#34;&gt;seekport&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The interface is in German but it supports searching in English just fine. The default language is selected by your locale. It’s really good considering its small index; it hasn’t heard of less common terms, but it’s able to find relevant results in other tests. It&amp;rsquo;s the second-fastest-improving engines in this section.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.exalead.com/search/&#34;&gt;Exalead&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Slow, quality is hit-and-miss. Its indexer claims to crawl the DMOZ directory, which has since shut down and been replaced by the &lt;a href=&#34;https://curlie.org&#34;&gt;Curlie&lt;/a&gt; directory. No relevant results for &amp;ldquo;Oppenheimer&amp;rdquo; and some other history-related queries. Allows submitting individual URLs for indexing, but requires solving a Google reCAPTCHA and entering an email address.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.exactseek.com/&#34;&gt;ExactSeek&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Small index, disproportionately dominated by big sites. Failed multiple tests. Allows submitting individual URLs for crawling, but requires entering an email address and receiving a newsletter. Webmaster tools seem to heavily push for paid &lt;abbr title=&#34;search-engine optimization&#34;&gt;SEO&lt;/abbr&gt; options. It also powers SitesOnDisplay and &lt;a href=&#34;https://www.blog-search.com&#34;&gt;Blog-&lt;wbr /&gt;search.com&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://burf.co/&#34;&gt;Burf.co&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Very small index, but seems fine at ranking more relevant results higher. Allows site submission without any extra steps.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.chatnoir.eu/&#34;&gt;ChatNoir&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;An experimental engine by researchers that uses the &lt;a href=&#34;https://commoncrawl.org/&#34;&gt;Common Crawl&lt;/a&gt; index. The engine is &lt;a href=&#34;https://github.com/chatnoir-eu&#34;&gt;open source&lt;/a&gt;. See the &lt;a href=&#34;https://groups.google.com/g/common-crawl/c/3o2dOHpeRxo/m/H2Osqz9dAAAJ&#34;&gt;announcement&lt;/a&gt; on the Common Crawl mailing list (Google Groups).&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;http://www.secretsearchenginelabs.com/&#34;&gt;Secret Search Engine Labs&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Very small index with very little SEO spam; it toes the line between a &amp;ldquo;search engine&amp;rdquo; and a &amp;ldquo;surf engine&amp;rdquo;. It&amp;rsquo;s best for reading about broad topics that would otherwise be dominated by SEO spam, thanks to its &lt;a href=&#34;http://www.secretsearchenginelabs.com/tech/cashrank.php&#34;&gt;CashRank algorithm&lt;/a&gt;. Allows site submission.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.gabanza.com/&#34;&gt;Gabanza&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A search engine from a hosting company. I found few details abou the search engine itself, and the index was small, but it was suitable for discovering new pages related to short broad queries.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://jambot.com/&#34;&gt;Jambo&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Docs, blog posts, etc. have not been updated since around 2006 but the engine continues to crawl and index new pages. Discovered in my access logs. Has a bias towards older content.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;http://search.dxhub.de/?c=main&#34;&gt;search.dxhub.de&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;While Gigablast seems dead, a version of it was open-source. This is based on that version of Gigablast. Its index is small but results are still useful for surfing new unseen corners of short-tail queries. Found via my access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://fynd.bot/&#34;&gt;Fynd&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Does not appear to support full-page search, but does search page titles and description meta-tags. Supports URL submission. Found in my access logs. Currently in a prototype/experimental stage.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;fledgling-engines&#34;&gt;Fledgling engines&lt;/h3&gt;
&lt;p&gt;Results from these search engines don&amp;rsquo;t seem particularly relevant; indexes in this category tend to be small.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.yessle.com/&#34;&gt;Yessle&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Seems new; allows page submission by pasting a page into the search box. Index is really small but it crawls new sites quickly. Claims to be private.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://search.aibull.io/&#34;&gt;Bloopish&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Extremely quick to update its index; site submissions show up in seconds. Unfortunately, its index only contains a few thousand documents (under 100 thousand at the time of writing). It&amp;rsquo;s growing fast: if you search for a term, it&amp;rsquo;ll start crawling related pages and grow its index.&lt;/dd&gt;
&lt;dt&gt;YaCy&lt;/dt&gt;
&lt;dd&gt;Community-made index; slow. Results are awful/irrelevant, but can be useful for intranet or custom search.&lt;/dd&gt;
&lt;dt&gt;Scopia&lt;/dt&gt;
&lt;dd&gt;Only seems to be available via the &lt;a href=&#34;https://metager.org&#34;&gt;MetaGer&lt;/a&gt; metasearch engine after turning off Bing and news results. Tiny index, very low-quality. As of &lt;time&gt;2024-09-10&lt;/time&gt;, &lt;a href=&#34;https://suma-ev.de/en/eine-aera-geht-zu-ende/&#34;&gt;MetaGer is paid-only after losing its advertising contract with Yahoo&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.artadosearch.com/&#34;&gt;Artado Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Primarily Turkish, but it also seems to support English results. Like Plumb, it uses client-side JS to fetch results from existing engines (Google, Bing, Yahoo, Petal, and others); like MetaGer, it has an option to use its own independent index. Results from its index are almost always empty. Very simple queries (&amp;ldquo;twitter&amp;rdquo;, &amp;ldquo;wikipedia&amp;rdquo;, &amp;ldquo;reddit&amp;rdquo;) give some answers. Supports site submission and crowdsourced instant answers.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.activesearchresults.com&#34;&gt;Active Search Results&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Very poor quality. Results seem highly biased towards commercial sites.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.crawlson.com&#34;&gt;Crawlson&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Young, slow. In this category because its index has a cap of 10 URLs per domain. I initially discovered Crawlson in the seirdy.one access logs. This is often down; if the current downtime persists, I&amp;rsquo;ll add it to the graveyard.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.anoox.com/&#34;&gt;Anoox&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Results are few and irrelevant; fails to find any results for basic terms. Allows site submission. It&amp;rsquo;s also a lightweight social network and claims to be powered by its users, letting members vote on listings to alter rankings.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.yioop.com&#34;&gt;Yioop!&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A FLOSS search engine that boasts a very impressive &lt;a href=&#34;https://www.seekquarry.com/&#34;&gt;feature-set&lt;/a&gt;: it can parse sitemaps, feeds, and a variety of markup formats; it can import pre-curated data in forms such as access logs, Usenet posts, and WARC archives; it also supports feed-based news search. Despite the impressive feature set, Yioop&amp;rsquo;s results are few and irrelevant due to its small index. It allows submitting sites for crawling. Like Meorca, Yioop has social features such as blogs, wikis, and a chat bot API.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://spyda.dev/&#34;&gt;Spyda&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;span
	class=&#34;h-cite&#34;&gt;A small engine made by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.prologic.blog/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;James&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Mills&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;, described in &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.prologic.blog/2021/02/14/so-im-a.html&#34;&gt;So I’m a Knucklehead eh?&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. It&amp;rsquo;s written in Go; check out its &lt;a href=&#34;https://git.mills.io/prologic/spyda&#34;&gt;MIT-licensed Spyda source code&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.slzii.com/&#34;&gt;Slzii.com&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A new web portal with a search engine. Has a tiny index dominated by SEO spam. Discovered in the seirdy.one access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.weblogdb.com/&#34;&gt;Weblog DataBase&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A metadata search engine for technical blogs. Very small index and ranking seems poor, but it seems to have &lt;a href=&#34;https://www.weblogdb.com/about/&#34;&gt;different goals from most search engines&lt;/a&gt;: it encourages filtering search results iteratively until finding the desired subset of results. The index updates weekly and not all features are implemented yet.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;semi-independent-indexes&#34;&gt;Semi-independent indexes&lt;/h3&gt;
&lt;p&gt;Engines in this category fall back to GBY when their own indexes don&amp;rsquo;t have enough results. As their own indexes grow, some claim that this should happen less often.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://search.brave.com/&#34;&gt;Brave Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Many tests (including all the tests I listed in the &amp;ldquo;Methodology&amp;rdquo; section) resulted results identical to Google, revealed by a side-by-side comparison with Google, Startpage, and a Searx instance with only Google enabled. Brave claims that this is due to how Cliqz (the discontinued engine acquired by Brave) used query logs to build its page models and was optimized to match Google.&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt; The index is independent, but optimizing against Google resulted in too much similarity for the real benefit of an independent index to show. Furthermore, many queries have Bing results mixed in; users can click an &amp;ldquo;info&amp;rdquo; button to see the percentage of results that came from its own index. The independent percentage is typically quite high (often close to 100% independent) but can drop for advanced queries. &lt;ins cite=&#34;https://brave.com/search-independence/&#34; datetime=&#34;2023-08-15T20:39:00-07:00&#34;&gt;Update 2023-08-15: Brave&amp;rsquo;s Bing contract appears to have expired as of April 2023.&lt;/ins&gt;
&lt;p&gt;I can&amp;rsquo;t in good conscience recommend using Brave Search, as the company runs cryptocurrency, has &lt;a href=&#34;https://brave.com/rewards-update/&#34;&gt;held payments to creators without disclosing that creators couldn&amp;rsquo;t receive rewards&lt;/a&gt;, has made dangerously misleading claims about fingerprinting resistance,&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; is run by a CEO who &lt;a href=&#34;https://arstechnica.com/information-technology/2014/03/new-mozilla-ceo-issues-statement-expresses-sorrow-for-causing-pain/&#34;&gt;spent thousands of dollars opposing gay marriage&lt;/a&gt;, and &lt;a href=&#34;https://www.pcmag.com/news/brave-browser-caught-redirecting-users-through-affiliate-links&#34;&gt;has rewritten typed URLs with affiliate links&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Brave Search offers a Tor onion service and doesn&amp;rsquo;t require JS. Powers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ghostery Private Search (identical results in my tests).&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Partially powers Kagi (&lt;a href=&#34;https://web.archive.org/web/20231105004927/https://help.kagi.com/kagi/search-details/search-sources.html&#34;&gt;documented in 2023&lt;/a&gt;, &lt;a href=&#34;https://github.com/kagisearch/kagi-docs/commit/6baff1c066db9b3d804653ea19bc9d1c076a710b&#34;&gt;unclear after docs removed main sources after &lt;time&gt;2024-05-01&lt;/time&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Powers &lt;a href=&#34;https://good-search.org/en/&#34;&gt;GOOD Search&lt;/a&gt; (&lt;a href=&#34;https://web.archive.org/web/20250313144823/https://good-search.org/en/&#34;&gt;archived homepage&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://plumb.one/&#34;&gt;Plumb&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Almost all queries return no results; when this happens, it falls back to Google. It&amp;rsquo;s fairly transparent about the fallback process, but I&amp;rsquo;m concerned about &lt;em&gt;how&lt;/em&gt; it does this: it loads Google&amp;rsquo;s Custom Search scripts from &lt;code&gt;cse.google.com&lt;/code&gt; onto the page to do a client-side Google search. This can be mitigated by using a browser addon to block &lt;code&gt;cse.google.com&lt;/code&gt; from loading any scripts. Plumb claims that this is a temporary measure while its index grows, and they&amp;rsquo;re planning on getting rid of this. Allows submitting URLs, but requires solving an hCaptcha. This engine is very new; hopefully as it improves, it could graduate from this section. Its Chief Product Officer &lt;a href=&#34;https://archive.is/oVAre&#34;&gt;previously founded&lt;/a&gt; the Gibiru search engine which shares the same affiliates and (for now) the same index; the indexes will diverge with time.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.qwant.com&#34;&gt;Qwant&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Qwant claims to use its own index, but it still relies on Bing for most results. It seems to be in a position similar to Neeva. Try a side-by-side comparison to see if or how it compares with Bing.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://kagi.com/&#34;&gt;Kagi Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The most interesting entry in this category, IMO. Like Neeva, it requires an account and limits use without payment. It&amp;rsquo;s powered by its own Teclis index (Teclis can be used independently; see the &lt;a href=&#34;#small-or-non-commercial-web&#34;&gt;non-commercial section&lt;/a&gt; below), and claims to also use results from Google and Bing. The result seems somewhat unique: I&amp;rsquo;m able to recognize some results from the Teclis index mixed in with the mainstream ones. In addition to Teclis, Kagi&amp;rsquo;s other products include the &lt;a href=&#34;https://kagi.ai/&#34;&gt;Kagi.ai&lt;/a&gt; intelligent answer service and the &lt;a href=&#34;https://tinygem.org/&#34;&gt;TinyGem&lt;/a&gt; social bookmarking service, both of which play a role in Kagi.com in the present or future. Unrelatedly: I&amp;rsquo;m concerned about the company&amp;rsquo;s biases, as it seems happy to &lt;a href=&#34;https://kagifeedback.org/d/2808-reconsider-your-partnership-with-brave&#34;&gt;use Brave&amp;rsquo;s commercial API&lt;/a&gt; (allowing blatant homophobia in the comments) and &lt;a href=&#34;https://kagifeedback.org/d/865-suicide-results-should-probably-have-a-dont-do-that-widget-like-google/50&#34;&gt;allow its results to recommend suicide methods without intervention&lt;/a&gt;. I reject the idea that avoiding an option that may seem politically biased is the same as being unbiased if such a decision has real political implications.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://prieco.net/&#34;&gt;PriEco&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A metasearch engine with one option for using its own index. Found in my access logs. All other sources can be turned off, allowing you to see its unique results. At the time of writing, its own index is unfortunately quite tiny.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;non-generalist-search&#34;&gt;Non-generalist search&lt;/h2&gt;
&lt;p&gt;These indexing search engines don’t have a Google-like “ask me anything” endgame; they’re trying to do something different. You aren&amp;rsquo;t supposed to use these engines the same way you use GBY.&lt;/p&gt;
&lt;h3 id=&#34;small-or-non-commercial-web&#34;&gt;Small or non-commercial Web&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://search.marginalia.nu/&#34;&gt;Marginalia Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;em&gt;My favorite entry on this page&lt;/em&gt;. It has its own crawler but is strongly biased towards non-commercial, personal, and/or minimal sites. It&amp;rsquo;s a great response to the increasingly SEO-spam-filled SERPs of GBY. Partially powers Teclis, which in turn partially powers Kagi. &lt;ins cite=&#34;https://memex.marginalia.nu/log/58-marginalia-open-source.gmi&#34; datetime=&#34;2022-05-28T14:09:00-07:00&#34;&gt;Update 2022-05-28: &lt;a href=&#34;https://memex.marginalia.nu/log/58-marginalia-open-source.gmi&#34;&gt;Marginalia.nu is now open source.&lt;/a&gt;&lt;/ins&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://ichi.do/&#34;&gt;Ichido&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;An engine that just rolled out its own independent index, with a lot of careful thought put into its ranking algorithm. Like Marginalia, it&amp;rsquo;s biased towards the non-commercial Web: it downranks ads, CAPTCHAs, trackers, SEO, and obfuscation. &lt;a href=&#34;https://blog.ichi.do/post/2023/08/20/a-new-ichido/&#34;&gt;More info about Ichido is in a blog post&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;http://teclis.com/&#34;&gt;Teclis&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A project by the creator of Kagi search. Uses its own crawler that measures content blocked by uBlock Origin, and extracts content with the open-source article scrapers Trafilatura and Readability.js. This is quite an interesting approach: tracking blocked elements discourages tracking and advertising; using Trafilatura and Readability.js encourages the use of semantic HTML and Semantic Web standards such as &lt;a href=&#34;https://microformats.org/&#34;&gt;microformats&lt;/a&gt;, &lt;a href=&#34;https://html.spec.whatwg.org/multipage/microdata.html&#34;&gt;microdata&lt;/a&gt;, and &lt;a href=&#34;https://www.w3.org/TR/rdfa-primer/&#34;&gt;RDFa&lt;/a&gt;. It claims to also use some results from Marginalia. &lt;a href=&#34;https://kagifeedback.org/d/1838-teclis-is-broken/2&#34;&gt;The Web interface has been shut down&lt;/a&gt;, but its standalone API is still available for Kagi customers.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://clew.se/&#34;&gt;Clew&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;a FOSS new engine with a small index of several thousand pages. It focuses on independent content and downranks ads and trackers; there seems to be a real focus on quality over quantity, which makes it excellent for short-tail searches (especially around technical concepts). Ranking is more egalitarian than other engines, making it better for discovery and surfing than research. It&amp;rsquo;s designed to be small and lightweight, with a compact index. Discovered in the seirdy.one access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://search.lixialabs.com/&#34;&gt;Lixia Labs Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A new engine that focuses on indexing technical websites and blogs, with a minimal JavaScript-free front-end. Discovered in my access logs. Surprisingly good results for broad technical keyword queries.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;site-finders&#34;&gt;Site finders&lt;/h3&gt;
&lt;p&gt;These engines try to find a website, typically at the domain-name level. They don&amp;rsquo;t focus on capturing particular pages within websites.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://kozmonavt.ml/&#34;&gt;Kozmonavt&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The best in this category. Has a small but growing index of over 8 million sites. If I want to find the website for a certain project, Kozmonavt works well (provided its index has crawled said website). It works poorly for learning things and finding general information. I cannot recommend it for anything serious since it lacks contact information, a privacy policy, or any other information about the org/people who made it. Discovered in the seirdy.one access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;http://www.search.tl/&#34;&gt;search.tl&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Generalist search for one &lt;abbr title=&#34;top-level domain&#34;&gt;TLD&lt;/abbr&gt; at a time (defaults to .com). I&amp;rsquo;m not sure why you&amp;rsquo;d want to always limit your searches to a single TLD, but now you can.&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt; There isn&amp;rsquo;t any visible UI for changing the TLD for available results; you need to add/change the &lt;code&gt;tld&lt;/code&gt; URL parameter. For example, to search .org sites, append &lt;code&gt;&amp;amp;tld=org&lt;/code&gt; to the URL. It seems to be connected to &lt;a href=&#34;http://www.amidalla.de/&#34;&gt;Amidalla&lt;/a&gt;. Amidalla allows users to manually add URLs to its index and directory; I have yet to see if doing so impacts search.tl results.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://search.thunderstone.com/&#34;&gt;Thunderstone&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A combined website catalog and search engine that focuses on categorization. Its &lt;a href=&#34;https://search.thunderstone.com/texis/websearch19/about.html&#34;&gt;about page&lt;/a&gt; claims: &lt;q cite=&#34;https://search.thunderstone.com/texis/websearch19/about.html&#34;&gt;We continuously survey all primary COM, NET, and ORG web-servers and distill their contents to produce this database. This is an index of &lt;em&gt;sites&lt;/em&gt; not pages. It is very good at finding companies and organizations by purpose, product, subject matter, or location. If you&amp;rsquo;re trying to finding things like &lt;em&gt;&amp;lsquo;BillyBob&amp;rsquo;s personal beer can page on AOL&amp;rsquo;&lt;/em&gt;, try Yahoo or Dogpile.&lt;/q&gt; This seems to be the polar opposite of the engines in the &lt;a href=&#34;#small-or-non-commercial-web&#34;&gt;&amp;ldquo;small or non-commercial Web&amp;rdquo; category&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.sengine.info/&#34;&gt;sengine.info&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Only shows domains, not individual pages. Developed by netEstate GmbH, which specializes in content extraction for inprints and job ads. Also has a German-only version available. Discovered in my access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.gnomit.com/&#34;&gt;Gnomit&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Allows single-keyword queries and returns sites that seem to cover a related topic. I actually kind of enjoy using it; results are old (typically from 2009) and a bit random, but make for a nice way to discover something new. For instance, searching for &amp;ldquo;IRC&amp;rdquo; helped me discover new IRC networks I&amp;rsquo;d never heard of.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;other&#34;&gt;Other&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://highbrow.se/&#34;&gt;High Browse&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Uses a non-traditional ranking algorithm which does an excellent job of introducing non-SEO-optimized serendipity into search results. One of my favorite &amp;ldquo;surf-engines&amp;rdquo;, as opposed to traditional &amp;ldquo;search-engines&amp;rdquo;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.keybot.com/&#34;&gt;Keybot&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A must-have for anyone who does translation work. It crawls the web looking for multilingual websites. Translators who are unsure about how to translate a given word or phrase can see its usage in two given languages, to learn from other human translators. My parents are fluent English speakers but sometimes struggle to express a given Hindi idiom in English; something like this could be useful to them, since machine translation isn&amp;rsquo;t nuanced enough for every situation. Part of the &lt;a href=&#34;https://www.ttn.ch/&#34;&gt;TTN Translation Network&lt;/a&gt;. Discovered in my access logs.&lt;/dd&gt;
&lt;dt&gt;Quor&lt;/dt&gt;
&lt;dd&gt;Seems to mainly index large news sites. Site is down as of June 2021; originally available at www dot quor dot com.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.semanticscholar.org/&#34;&gt;Semantic Scholar&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A search engine by the Allen Institute for AI focused on academic PDFs, with a couple hundred million papers indexed. Discovered in my access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://bonzamate.com.au/&#34;&gt;Bonzamate&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A search engine specifically for Australian websites. Boyter wrote &lt;a href=&#34;https://boyter.org/posts/abusing-aws-to-make-a-search-engine/&#34;&gt;an interesting blog post about Bonzamate&lt;/a&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://searchcode.com/&#34;&gt;searchcode&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A code-search engine by the developer of Bonzamate. Searches a hand-picked list of code forges for source code, supporting many search operators.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://star-finder.de/?l=en&#34;&gt;StarFinder&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A search engine that focuses on Open Graph Protocol metadata, searching for domains that have OGP information and rendering link previews for them. A good surf-engine once you grok how to build sufficiently broad queries. Has a large and growing index of 4.8 million sites at the time of writing. Allows site submission.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;other-languages&#34;&gt;Other languages&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m unable to evaluate these engines properly since I don&amp;rsquo;t speak the necessary languages. English searches on these are a hit-or-miss. I might have made a few mistakes in this category.&lt;/p&gt;
&lt;h3 id=&#34;big-indexes&#34;&gt;Big indexes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Baidu: Chinese. Very large index; it&amp;rsquo;s a major engine alongside GBY. Offers webmaster tools for site submission.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Qihoo 360: Chinese. I&amp;rsquo;m not sure how independent this one is.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Toutiao: Chinese. Not sure how independent this one is either. Its index appears limited outside of its own content distribution platform.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sogou: Chinese&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yisou: Chinese, by Yahoo. Appears defunct.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://search.naver.com&#34;&gt;Naver&lt;/a&gt;: Korean. Allows submitting sitemaps and feeds. Discovered via some Searx metasearch instances.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.daum.net/&#34;&gt;Daum&lt;/a&gt;: Korean. Also unsure about this one&amp;rsquo;s independence.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.seznam.cz/&#34;&gt;Seznam&lt;/a&gt;: Czech, seems relatively privacy-friendly. Discovered in the seirdy.one access logs. It allows site submission with webmaster tools. &lt;a href=&#34;https://blog.seznam.cz/2022/03/mate-novy-obsah-dejte-o-nem-hned-vsem-vedet-pomoci-indexnow/&#34;&gt;Seznam supports IndexNow&lt;/a&gt;; it shares IndexNow-submitted pages with Bing and Yandex.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://coccoc.com/search&#34;&gt;Cốc Cốc&lt;/a&gt;: Vietnamese&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://go.mail.ru/&#34;&gt;go.mail.ru&lt;/a&gt;: Russian&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://letsearch.ru/&#34;&gt;LetSearch.ru&lt;/a&gt;: Russian. &lt;a href=&#34;https://letsearch.ru/bots&#34;&gt;Allows URL submission&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;smaller-indexes&#34;&gt;Smaller indexes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.alibw.com/&#34;&gt;ALibw.com&lt;/a&gt;: Chinese, found in my access logs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.vuhuv.com.tr/&#34;&gt;Vuhuv&lt;/a&gt;: Turkish. &lt;a href=&#34;https://tr.vuhuv.com/&#34;&gt;alt domain&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.search.ch&#34;&gt;search.ch&lt;/a&gt;: Regional search engine for Switzerland; users can restrict searches to their local regions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.fastbot.de/&#34;&gt;fastbot&lt;/a&gt;: German&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://solofield.net&#34;&gt;SOLOFIELD&lt;/a&gt;: Japanese&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://kaz.kz&#34;&gt;kaz.kz&lt;/a&gt;: Kazakh and Russian, with a focus on &amp;ldquo;Kazakhstan&amp;rsquo;s segment of the Internet&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;almost-qualified&#34;&gt;Almost qualified&lt;/h2&gt;
&lt;p&gt;These engines come close enough to passing my inclusion criteria that I felt I had to mention them. They all display original organic results that you can&amp;rsquo;t find on other engines, and maintain their own indexes. Unfortunately, they don&amp;rsquo;t quite pass because they don&amp;rsquo;t crawl the Web; most limit themselves to a specific set of sites.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://wiby.me&#34;&gt;wiby.me&lt;/a&gt; OR &lt;a href=&#34;https://wiby.org&#34;&gt;wiby.org&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;I love this one. It focuses on smaller independent sites that capture the spirit of the &amp;ldquo;early&amp;rdquo; web. It&amp;rsquo;s more focused on &amp;ldquo;discovering&amp;rdquo; new interesting pages that match a set of keywords than finding a specific resources. I like to think of Wiby as an engine for surfing, not searching. Runnaroo occasionally featured a hit from Wiby (Runnaroo has since shut down). If you have a small site or blog that isn&amp;rsquo;t very &amp;ldquo;commercial&amp;rdquo;, consider submitting it to the index. Does not qualify because it seems to be powered only by user-submitted sites; it doesn&amp;rsquo;t try to &amp;ldquo;crawl the Web&amp;rdquo;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://mwmbl.org/&#34;&gt;Mwmbl&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Like YaCy, it&amp;rsquo;s an open-source engine whose crawling is community-driven. Users can install a Firefox addon to crawl pages in its backlog. Unfortunately, it doesn&amp;rsquo;t qualify because it only crawls pages linked by hand-picked sites (e.g. Wikipedia, GitHub, domains that rank well on Hacker News). The crawl-depth is &amp;ldquo;1&amp;rdquo;, so it doesn&amp;rsquo;t crawl the whole Web (yet).&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://searchmysite.net&#34;&gt;Search My Site&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Similar to Marginalia and Teclis, but only indexes user-submitted personal and independent sites. It optionally supports IndieAuth. Its API powers this site&amp;rsquo;s search results; try it out using the search bar at the bottom of this page. Does not qualify because it&amp;rsquo;s limited to user-submitted and/or hand-picked sites.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://kukei.eu/&#34;&gt;Kukei.eu&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A curated search engine for web developers, which crawls &lt;a href=&#34;https://github.com/Kukei-eu/spider/blob/914b8dfffc10cb3a948561aef2bf86937d3a0b2e/index-sources.js&#34;&gt;a hand-picked list of sites&lt;/a&gt;. As it does not index the whole Web, it doesn&amp;rsquo;t qualify. I still find it interesting.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://unobtanium.rocks/&#34;&gt;Unobtanium Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A fledgling search engine by &lt;a href=&#34;https://slatecave.net/&#34;&gt;Slatian&lt;/a&gt;. At the time of writing, it crawls hand-curated sites: personal, technical, indie wiki, and German hacker community sites. It may eventually crawl government/public-service sites. More documentation will be on its website.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;misc&#34;&gt;Misc&lt;/h2&gt;
&lt;dl&gt;
&lt;dt&gt;Ask.com&lt;/dt&gt;
&lt;dd&gt;The site is back. They claim to outsource search results. The results seem similar to Google, Bing, and Yandex; however, I can’t pinpoint exactly where their results are coming from. Also, several sites from the &amp;ldquo;ask.com network&amp;rdquo; such as directhit.com, info.com, and kensaq.com have uniqe-looking results.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://infinitysearch.co&#34;&gt;Infinity Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Partially evaluated. Young, small index. It recently split into a paid offering with the main index and &lt;a href=&#34;https://infinitydecentralized.com/&#34;&gt;Infinity Decentralized&lt;/a&gt;, the latter of which allows users to select from community-hosted crawlers. I managed to try it out before it became a paid offering, and it seemed decent; however, I wasn&amp;rsquo;t able to run the tests listed in the &amp;ldquo;Methodology&amp;rdquo; section. Allows submitting URLs and sitemaps into a text box, no other work required.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2 id=&#34;search-engines-without-a-web-interface&#34;&gt;Search engines without a web interface&lt;/h2&gt;
&lt;p&gt;Some search engines are integrated into other appliances, but don&amp;rsquo;t have a web portal.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Apple&amp;rsquo;s search engine is usable in the form of &amp;ldquo;Siri Suggested Websites&amp;rdquo;. Its index is built from the Applebot web crawler. If Apple already has working search engine, it&amp;rsquo;s not much of a stretch to say that they&amp;rsquo;ll make a web interface for it someday.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Amazon bought Alexa Internet (a web traffic analysis company, at the time unrelated to the Amazon Alexa virtual assistant) and discontinued its website ranking product. Amazon still runs the relevant crawlers, and also have &lt;a href=&#34;https://developer.amazon.com/support/amazonbot&#34;&gt;a bot called &amp;ldquo;Amazonbot&amp;rdquo;&lt;/a&gt;. While Applebot powers the Siri personal assistant, Amazonbot powers the Alexa personal assistant &lt;q cite=&#34;https://developer.amazon.com/support/amazonbot&#34;&gt;to answer even more questions for customers&lt;/q&gt;. Crawling the web to answer questions is the basis of a search engine.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;graveyard&#34;&gt;Graveyard&lt;/h2&gt;
&lt;p&gt;These engines were originally included in the article, but have since been discontinued.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20230118225122/https://www.petalsearch.com/&#34;&gt;Petal Search&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A search engine by Huawei that recently switched from searching for Android apps to general search in order to reduce dependence on Western search providers. Despite its surprisingly good results, I wouldn&amp;rsquo;t recommend it due to privacy concerns: its privacy policy describes advanced fingerprinting metrics, and it doesn&amp;rsquo;t work without JavaScript. Requires an account to submit sites. I discovered this via my access logs. Be aware that in some jurisdictions, it doesn&amp;rsquo;t use its own index: in Russia and some EU regions it uses Yandex and Qwant, respectively. Inaccessible as of June 2023.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20230528051432/https://neeva.com/blog/may-announcement&#34;&gt;Neeva&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Formerly in &lt;a href=&#34;#semi-independent-indexes&#34;&gt;the &amp;ldquo;semi-independent&amp;rdquo; section&lt;/a&gt;. Combined Bing results with results from its own index. Bing normally isn&amp;rsquo;t okay with this, but Neeva was one of few exceptions. Results were mostly identical to Bing, but original links not found by Bing frequently popped up. Long-tail and esoteric queries were less likely to feature original results. Required signing up with an email address or OAuth to use, and offered a paid tier with additional benefits. Acquired by Snowflake and announced its shut-down in May 2023.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://gigablast.com/&#34;&gt;Gigablast&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;It&amp;rsquo;s been around for a while and also sports a classic web directory. Searches are a bit slow, and it charges to submit sites for crawling. It powers &lt;a href=&#34;https://private.sh&#34;&gt;Private.sh&lt;/a&gt;. Gigablast was tied with Right Dao for quality. Shut down mid-2023.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://xangis.com/the-wbsrch-experiment/&#34;&gt;wbsrch&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;In addition to its generalist search, it also had many other utilities related to domain name statistics. Failed multiple tests. Its index was a bit dated; it had an old backlog of sites it hadn&amp;rsquo;t finished indexing. It also had several dedicated per-language indexes.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20211226043304/https://www.gowiki.com/&#34;&gt;Gowiki&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Very young, small index, but showed promise. I discovered this in the seirdy.one access logs. It was only available in the US. Seems down as of early 2022.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20220429143153/https://www.meorca.com/search/&#34;&gt;Meorca&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A UK-based search engine that claims not to &amp;ldquo;index pornography or illegal content websites&amp;rdquo;. It also features an optional social network (&amp;ldquo;blog&amp;rdquo;). Discovered in the seirdy.one access logs.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20220624172257/https://ninfex.com/&#34;&gt;Ninfex&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A &amp;ldquo;people-powered&amp;rdquo; search engine that combines aspects of link aggregators and search. It lets users vote on submissions and it also displays links to forums about submissions.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/isovector/marlo&#34;&gt;Marlo&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Another FLOSS engine: Marlo is written in Haskell. Has a small index that&amp;rsquo;s good enough for surfing broad topics, but not good enough for specific research. Originally available at &lt;code&gt;marlo.sandymaguire.me&lt;/code&gt;.&lt;/dd&gt;
&lt;dt&gt;websearchengine.org OR tuxdex.com&lt;/dt&gt;
&lt;dd&gt;Both were run by the same people, powered by their inetdex.com index. Searches are fast, but crawls are a bit shallow. Claims to have an index of 10 million domains, and not to use cookies. The pages are currently down and the domains re-direct to porn sites; I&amp;rsquo;m not aware of any official notice.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20230810032916/https://entfer.com/&#34;&gt;Entfer&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;a newcomer that let registered users upvote/downvote search results to customize ranking. Didn&amp;rsquo;t offer much information about who made it. Its index was small, but it did seem to return results related to the query.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20221002041725/https://siik.co/&#34;&gt;Siik&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Lacked contact info, and the ToS and Privacy Policy links were dead. Seemed to have PHP errors in the backend for some of its instant-answer widgets. If you scrolled past all that, you&amp;rsquo;d find web results powered by what seems to be its own index. These results did tend to be somewhat relevant, but the index seemed too small for more specific queries.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://blogsurf.io/&#34;&gt;Blog Surf&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A search engine for blogs with RSS/Atom feeds. Originally in &amp;ldquo;almost qualified&amp;rdquo;. It did not qualify because all blogs submitted to the index require manual review, but it seemed interesting. Its &amp;ldquo;MarketRank&amp;rdquo; algorithm gave it a bias towards sites popular on &amp;ldquo;Hacker&amp;rdquo; &amp;ldquo;News&amp;rdquo;.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://web.archive.org/web/20250627183504/https://infotiger.com/&#34;&gt;Infotiger&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Was one of my favorites. It offered advanced result filtering and sports a somewhat large index. It allowed site submission for English and German pages. &lt;a href=&#34;http://infotiger4xywbfq45mvd5drh43jpqeurakg2ya7gqwvjf2bbwnixzqd.onion/&#34;&gt;Infotiger also had a Tor hidden service&lt;/a&gt;.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Dead engines I don&amp;rsquo;t have an extended description for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.parsijoo.ir/&#34;&gt;Parsijoo&lt;/a&gt;: Persian search engine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.moose.at&#34;&gt;Moose.at&lt;/a&gt;: German (Austria-based). The site is still up but redirects searches to Brave.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;upcoming-engines&#34;&gt;Upcoming engines&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://cyberfind.net/bot.html&#34;&gt;Cyberfind/find.tf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.wepch.com/search-engine&#34;&gt;Wepch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.weblogdb.com/&#34;&gt;Weblog DataBase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;exclusions&#34;&gt;Exclusions&lt;/h2&gt;
&lt;p&gt;Three engines were excluded from this list for having a far-right focus.&lt;/p&gt;
&lt;p&gt;One engine was excluded because it seems to be built using cryptocurrency in a way I&amp;rsquo;d rather not support.&lt;/p&gt;
&lt;p&gt;Some fascinating little engines seem like hobbyist proofs-of-concept. I decided not to include them in this list, but watch them with interest to see if they can become something viable.&lt;/p&gt;
&lt;h2 id=&#34;rationale&#34;&gt;Rationale&lt;/h2&gt;
&lt;p&gt;Why bother using non-mainstream search engines?&lt;/p&gt;
&lt;h3 id=&#34;conflicts-of-interest&#34;&gt;Conflicts of interest&lt;/h3&gt;
&lt;p&gt;Google, Microsoft (the company behind Bing), and Yandex aren&amp;rsquo;t just search engine companies; they&amp;rsquo;re content and ad companies as well. For example, Google hosts video content on YouTube and Microsoft hosts social media content on LinkedIn. This gives these companies a powerful incentive to prioritize their own content. They are able to do so even if they claim that they treat their own content the same as any other: since they have complete access to their search engines&amp;rsquo; inner workings, they can tailor their content pages to better fit their algorithms and tailor their algorithms to work well on their own content. They can also index their own content without limitations but throttle indexing for other crawlers.&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;One way to avoid this conflict of interest is to &lt;em&gt;use search engines that aren&amp;rsquo;t linked to major content providers;&lt;/em&gt; i.e., use engines with their own independent indexes.&lt;/p&gt;
&lt;h3 id=&#34;information-diversity&#34;&gt;Information diversity&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s also a practical, less-ideological reason to try other engines: different providers have different results. Websites that are hard to find on one search engine might be easy to find on another, so using more indexes and ranking algorithms results in access to more content.&lt;/p&gt;
&lt;p&gt;No search engine is truly unbiased. Most engines&amp;rsquo; ranking algorithms incorporate a method similar to &lt;a href=&#34;https://en.wikipedia.org/wiki/PageRank&#34;&gt;PageRank&lt;/a&gt;, which biases them towards sites with many backlinks. Search engines have to deal with unwanted results occupying the confusing overlap between SEO spam, shock content, and duplicate content. When this content’s manipulation of ranking algos causes it to rank high, engines have to address it through manual action or algorithm refinement. Choosing to address it through either option, or choosing to leave it there for popular queries after receiving user reports, reflects bias. The best solution is to mix different ranking algorithms and indexes instead of using one engine for everything.&lt;/p&gt;
&lt;h2 id=&#34;methodology&#34;&gt;Method­ology&lt;/h2&gt;
&lt;h3 id=&#34;discovery&#34;&gt;Discovery&lt;/h3&gt;
&lt;p&gt;I find new engines by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monitoring certain web directories for changes in their search engine listings.&lt;/li&gt;
&lt;li&gt;Checking other curated lists of &amp;ldquo;good/bad bots&amp;rdquo; to spot search engines.&lt;/li&gt;
&lt;li&gt;Using search engines to discover search engines: searching for the names of less-popular engines often pulls up similar lists.&lt;/li&gt;
&lt;li&gt;Receiving suggestions from readers&lt;/li&gt;
&lt;li&gt;Compiling a list of regular expressions for user-agent strings I&amp;rsquo;m familiar with. Before I delete my server access logs, I extract user-agents that don&amp;rsquo;t match that list along with the pages they request.&lt;/li&gt;
&lt;li&gt;Checking the Searx and Searxng projects for new integrations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;criteria-for-inclusion&#34;&gt;Criteria for inclusion&lt;/h3&gt;
&lt;p&gt;Engines in this list should have their own indexes powered by web crawlers. Original results should not be limited to a set of websites hand-picked by the engine creators; indexes should be built from sites from across the Web. An engine should discover new interesting places around the Web.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an oversimplified example to illustrate what I&amp;rsquo;m looking for: imagine somone self-hosts their own personal or interest-specific website and happens to get some recognition. Could they get &lt;em&gt;automatically&lt;/em&gt; discovered by your crawler, indexed, and included in the first page of results for a certain query?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m willing to make two exceptions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Engines in the &amp;ldquo;semi-independent&amp;rdquo; section may mix results that do meet the aforementioned criteria with results that do not.&lt;/li&gt;
&lt;li&gt;Engines in the &amp;ldquo;almost qualified&amp;rdquo; section may use indexes primarily made of user-submitted or hand-picked sites, rather than focusing primarily on sites discovered organically through crawling.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The reason the second exception exists is that while user submissions don&amp;rsquo;t represent automatic crawling, they do at least inform the engine of new interesting websites that it had not previously discovered; these websites can then be shown to other users. That&amp;rsquo;s fundamentally what an alternative web index needs to achieve.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not usually willing to budge on my &amp;ldquo;no hand-picked websites&amp;rdquo; rule. Hand-picked sites will be ignored, whether your engine fetches content through their APIs or crawls and scrapes their content. It&amp;rsquo;s fine to use hand-picked websites as starting points for your crawler (Wikipedia is a popular option).&lt;/p&gt;
&lt;p&gt;I only consider search engines that focus on link results for webpages. Image search engines are out of scope, though I &lt;em&gt;might&lt;/em&gt; consider some other engines for non-generalist search (e.g., Semantic Scholar finds PDFs rather than webpages).&lt;/p&gt;
&lt;h3 id=&#34;evaluation&#34;&gt;Evaluation&lt;/h3&gt;
&lt;p&gt;I focused almost entirely on &amp;ldquo;organic results&amp;rdquo; (the classic link results), and didn&amp;rsquo;t focus too much on (often glaring) privacy issues, &amp;ldquo;enhanced&amp;rdquo; or &amp;ldquo;instant&amp;rdquo; results (e.g. Wikipedia sidebars, related searches, Stack Exchange answers), or other elements.&lt;/p&gt;
&lt;p&gt;I compared results for esoteric queries side-by-side; if the first 20 results were (nearly) identical to another engine&amp;rsquo;s results (though perhaps in a slightly different order), they were likely sourced externally and not from an independent index.&lt;/p&gt;
&lt;p&gt;I tried to pick queries that should have a good number of results and show variance between search engines. An incomplete selection of queries I tested:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;vim&amp;rdquo;, &amp;ldquo;emacs&amp;rdquo;, &amp;ldquo;neovim&amp;rdquo;, and &amp;ldquo;nvimrc&amp;rdquo;: Search engines with relevant results for &amp;ldquo;nvimrc&amp;rdquo; typically have a big index. Finding relevant results for the text editors &amp;ldquo;vim&amp;rdquo; and &amp;ldquo;emacs&amp;rdquo; instead of other topics that share the name is a challenging task.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;vim cleaner&amp;rdquo;: should return results related to a &lt;a href=&#34;https://en.wikipedia.org/wiki/Vim_%28cleaning_product%29&#34;&gt;line of cleaning products&lt;/a&gt; rather than the Correct Text Editor.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;Seirdy&amp;rdquo;: My site is relatively low-traffic, but my nickname is pretty unique and visible on several of the highest-traffic sites out there.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;Project London&amp;rdquo;: a small movie made with volunteers and &lt;abbr title=&#34;Free, Libre, Open-Source Software&#34;&gt;FLOSS&lt;/abbr&gt; without much advertising. If links related to small independent projects like this show up, the index has really good coverage of movies.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;“oppenheimer” versus &amp;ldquo;J Robert Oppenheimer&amp;rdquo;: a name that could refer to many things. Without context, it could refer to a high-budget movie or the physicist who led the Manhattan Project in Los Alamos. Other historical queries: “magna carta” (intermediate), “the prince” (very hard).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(Update: I don&amp;rsquo;t use these queries anymore; I&amp;rsquo;ve found better tests in recent months).&lt;/p&gt;
&lt;p&gt;Some less-mainstream engines have noticed this article, which is great! I&amp;rsquo;ve had excellent discussions with people who work on several of these engines. Unfortunately, this article&amp;rsquo;s visibility also incentivizes some engines to optimize specifically for any methodology I describe. I&amp;rsquo;ve addressed this by keeping a long list of test queries to myself. The simple queries above are a decent starting point for simple quick evaluations, but I also test for common search operators, keyword length, and types of domain-specific jargon. I also use queries designed to pull up specific pages with varying levels of popularity and recency to gauge the size, scope, and growth of an index.&lt;/p&gt;
&lt;p&gt;Professional critics often work anonymously because personalization can damage the integrity of their reviews. For similar reasons, I attempt to try each engine anonymously at least once by using a VPN and/or my standard anonymous setup: an amnesiac Whonix VM with the Tor Browser. I also often test using a fresh profile when travelling, or via a Searx instance if it supports a given engine. When avoiding personalization, I use &amp;ldquo;varied&amp;rdquo; queries that I don&amp;rsquo;t repeat verbatim across search engines; this reduces the likelihood of identifying me. I also attempt to spread these tests out over time so admins won&amp;rsquo;t notice an unusual uptick in unpredictable and esoteric searches. This might seem overkill, but I already regularly employ similar methods for a variety of different scenarios.&lt;/p&gt;
&lt;h3 id=&#34;unique-results-without-unique-indexes&#34;&gt;Unique results without unique indexes&lt;/h3&gt;
&lt;p&gt;Some engines, like Kagi and the Ask.com family of engines, have unique-looking results from external indexes. Unique results alone don&amp;rsquo;t always imply independence, as an engine could alter ranking or add filters (something that very few engines are permitted to do; Google and Microsoft generally impose a strict ToS forbidding modification).&lt;/p&gt;
&lt;p&gt;Another possible indicator I look for is word substitutions. Nearly every engine supports substitutions for verb tense or singular/plural word forms, but more advanced semantic substitutions are less common. Returning the same results for &amp;ldquo;matza gebrent&amp;rdquo; and &amp;ldquo;matzo brei&amp;rdquo; requires a deep understanding of related food topics. Google and Bing return nearly identical results for the two queries, but engines like Mojeek return entirely different results. I often compare an engine&amp;rsquo;s word substitutions to see if they&amp;rsquo;re similar to another engine&amp;rsquo;s, and see how many results from the top 20 are not present in the top 30-40 on other engines. I have a working list of other word substitutions I test.&lt;/p&gt;
&lt;h3 id=&#34;caveats&#34;&gt;Caveats&lt;/h3&gt;
&lt;p&gt;I didn&amp;rsquo;t try to avoid personalization when testing engines that require account creation. Entries in the &amp;ldquo;hit-and-miss&amp;rdquo; and &amp;ldquo;unusable&amp;rdquo; sections got less attention: I didn&amp;rsquo;t spend a lot of effort tracking results over time to see how new entries got added to them.&lt;/p&gt;
&lt;p&gt;I avoided &amp;ldquo;natural language&amp;rdquo; queries like questions, focusing instead on keyword searches and search operators. I also mostly ignored infoboxes (also known as &amp;ldquo;instant answers&amp;rdquo;).&lt;/p&gt;
&lt;h2 id=&#34;findings&#34;&gt;Findings&lt;/h2&gt;
&lt;p&gt;What I learned by building this list has profoundly changed how I surf.&lt;/p&gt;
&lt;p&gt;Using one engine for everything ignores the fact that different engines have different strengths. For example: while Google is focused on being an &amp;ldquo;answer engine&amp;rdquo;, other engines are better than Google at discovering new websites related to a broad topic. Fortunately, browsers like Chromium and Firefox make it easy to add many search engine shortcuts for easy switching.&lt;/p&gt;
&lt;p&gt;When talking to search engine founders, I found that the biggest obstacle to growing an index is getting blocked by sites. Cloudflare was one of the worst offenders, although &lt;a href=&#34;https://blog.cloudflare.com/friendly-bots&#34;&gt;it has since launched a &amp;ldquo;verified bots&amp;rdquo; program to improve things&lt;/a&gt;. Too many sites block perfectly well-behaved crawlers, only allowing major players like Googlebot, BingBot, and TwitterBot; this cements the current duopoly over English search and is harmful to the health of the Web as a whole.&lt;/p&gt;
&lt;p&gt;Too many people optimize sites specifically for Google without considering the long-term consequences of their actions. One of many examples is how Google&amp;rsquo;s JavaScript support rendered the practice of testing a website without JavaScript or images &amp;ldquo;obsolete&amp;rdquo;: almost no non-GBY engines on this list are JavaScript-aware.&lt;/p&gt;
&lt;p&gt;When building webpages, authors need to consider the barriers to entry for a new search engine. The best engines we can build today shouldn&amp;rsquo;t replace Google. They should try to be different. We want to see the Web that Google won&amp;rsquo;t show us, and search engine diversity is an important step in that direction.&lt;/p&gt;
&lt;p&gt;Try a &amp;ldquo;bad&amp;rdquo; engine from lower in the list. It might show you utter crap. But every garbage heap has an undiscovered treasure. I&amp;rsquo;m sure that some hidden gems you&amp;rsquo;ll find will be worth your while. Let&amp;rsquo;s add some serendipity to the SEO-filled Web.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Acknow­ledgements&lt;/h2&gt;
&lt;p&gt;Some of this content came from the &lt;a href=&#34;https://www.searchenginemap.com/&#34;&gt;Search Engine Map&lt;/a&gt; and &lt;a href=&#34;https://searchengine.party/&#34;&gt;Search Engine Party&lt;/a&gt;. A few web directories also proved useful.&lt;/p&gt;
&lt;p&gt;&lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://web.archive.org/web/20230220000629/https://www.gigablast.com/bio.html&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Matt&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Wells&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
	from &lt;span class=&#34;p-org org&#34;&gt;
		&lt;a class=&#34;organization-name&#34; href=&#34;https://web.archive.org/web/20230331095814/https://www.gigablast.com/&#34;&gt;
			&lt;span&gt;Gigablast&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; also gave me some helpful information about GBY which I included in the &amp;ldquo;Rationale&amp;rdquo; section. He&amp;rsquo;s written more about big tech in the &lt;a href=&#34;https://web.archive.org/web/20230321113801/https://gigablast.com/blog.html&#34;&gt;Gigablast blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://thenewleafjournal.com/a-2021-list-of-alternative-search-engines-and-search-resources/&#34;&gt;A 2021 List of Alternative Search Engines and Search Resources&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://emucafe.club/channel/naferrell&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Nicholas&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Ferrell&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
from &lt;span class=&#34;p-org org&#34;&gt;
&lt;a class=&#34;organization-name&#34; href=&#34;https://thenewleafjournal.com/&#34;&gt;
&lt;span&gt;The New Leaf Journal&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is a great post on alternative search engines. He also gave me some &lt;a href=&#34;https://lists.sr.ht/~seirdy/seirdy.one-comments/%3C20210618031450.rb2twu4ypek6vvl3%40rkumarlappie.attlocal.net%3E&#34;&gt;useful details&lt;/a&gt; about Seznam, Naver, Baidu, and Goo.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Yes, &amp;ldquo;indexes&amp;rdquo; is an acceptable plural form of the word &amp;ldquo;index&amp;rdquo;. The word &amp;ldquo;indices&amp;rdquo; sounds weird to me outside a math class.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Update: &lt;a href=&#34;https://support.startpage.com/hc/en-us/articles/4522435533844-What-is-the-relationship-between-Startpage-and-your-search-partners-like-Google-and-Microsoft-Bing-&#34;&gt;A Startpage support article&lt;/a&gt; updated on &lt;time&gt;2023-03-08&lt;/time&gt; claims that Startpage uses Microsoft (probably Bing) too. In my own tests, I still see Google results. I&amp;rsquo;ll update its placement if this changes.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;DuckDuckGo has a crawler called DuckDuckBot. This crawler doesn&amp;rsquo;t impact the linked results displayed; it just grabs favicons and scrapes data for a few instant answers. DuckDuckGo&amp;rsquo;s help pages claim that the engine uses over 400 sources; my interpretation is that at least 398 sources don&amp;rsquo;t impact organic results. I don&amp;rsquo;t think DuckDuckGo is transparent enough about the fact that their organic results are proxied. Compare DuckDuckGo side-by-side with Bing and Yandex and you&amp;rsquo;ll see it&amp;rsquo;s sourcing organic results from one of them (probably Bing). &lt;em&gt;Update, March 2022:&lt;/em&gt; DuckDuckGo &lt;a href=&#34;https://web.archive.org/web/20220310222014/https://nitter.pussthecat.org/yegg/status/1501716484761997318&#34;&gt;has the ability to downrank results on its own&lt;/a&gt;; it was previously &lt;a href=&#34;https://www.nytimes.com/2022/02/23/technology/duckduckgo-conspiracy-theories.html&#34;&gt;working with Bing&lt;/a&gt; to get Bing to remove misinformation and spam.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Qwant claims to also use its own crawler for results, but it’s still mostly Bing in my experience. See the &amp;ldquo;semi-independent&amp;rdquo; section.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Disconnect Search allows users to have results proxied from Bing or Yahoo, but Yahoo sources its results from Bing.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Yippy claims to be powered by a certain IBM brand (a brand that could correspond to any number of products) and annotates results with the phrase &amp;ldquo;Yippy Index&amp;rdquo;, but a side-by-side comparison with Bing and other Bing-based engines revealed results to be nearly identical.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;I&amp;rsquo;m in the process of re-evaluating You.com. It claims to operate a crawler and index. It seems very much like DuckDuckGo&lt;sup id=&#34;fnref1:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; to me: organic results look like they&amp;rsquo;re from Bing, while infoboxes (&amp;ldquo;apps&amp;rdquo;) seem to be scraped or queried from hand-picked websites. I&amp;rsquo;m not currently seeing results from &amp;ldquo;around the web&amp;rdquo; like the other engines that do pass my inclusion criteria. I might be wrong! I&amp;rsquo;m re-evaluating it to see if this isn&amp;rsquo;t actually the case.&lt;/p&gt;
&lt;p&gt;&lt;ins datetime=&#34;2023-03-13T13:34:30-07:00&#34;&gt;Update: You.com seems to source organic link results from Bing, and only interleaves those results with its own curated infoboxes&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins datetime=&#34;2024-05-25&#34;&gt;Update: during a recent Bing outage, I found some organic link results on You.com that didn&amp;rsquo;t look like they came from Bing. More research is needed again.&lt;/ins&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://help.openai.com/en/articles/9237897-chatgpt-search&#34;&gt;the ChatGPT Search help article&lt;/a&gt;: &lt;q cite=&#34;https://help.openai.com/en/articles/9237897-chatgpt-search&#34;&gt;ChatGPT searches based on your prompts and may share disassociated search queries with third-party search providers such as Bing.&lt;/q&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;This is based on a statement Right Dao made in &lt;a href=&#34;https://reddit.com/comments/k4clx1/_/ge9dwmh/?context=1&#34;&gt;on Reddit&lt;/a&gt; (&lt;a href=&#34;https://web.archive.org/web/20210320042457/https://i.reddit.com/r/degoogle/comments/k4clx1/right_dao_a_new_independent_search_engine_that/ge9dwmh/?context=1&#34;&gt;archived&lt;/a&gt;).&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;More information can be found in &lt;a href=&#34;https://news.ycombinator.com/item?id=27593801&#34;&gt;this HN subthread&lt;/a&gt; and some posts on the Cliqz tech blog (&lt;a href=&#34;https://0x65.dev/blog/2019-12-06/building-a-search-engine-from-scratch.html&#34;&gt;one&lt;/a&gt;, &lt;a href=&#34;https://0x65.dev/blog/2019-12-10/search-quality-at-cliqz.html&#34;&gt;two&lt;/a&gt;).&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;I will explain my thinking in another post later, and then edit this with a link to that post.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://web.archive.org/web/20240721030135/https://www.ghostery.com/private-search&#34;&gt;Ghostery&amp;rsquo;s documentation at the time of writing&lt;/a&gt; is extremely misleading, using clever language that seems to heavily imply the use of an independent index and crawler while not saying so outright: Ghostery says it &lt;q cite=&#34;https://web.archive.org/web/20240721030135/https://www.ghostery.com/private-search&#34;&gt;gets you objective results from a unique search index&lt;/q&gt; and that it will &lt;q cite=&#34;https://web.archive.org/web/20240721030135/https://www.ghostery.com/private-search&#34;&gt;crawl it&amp;rsquo;s [sic] search index.&lt;/q&gt; Privacy claims require trust, and word games do little to build it.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;Some search engines support the &lt;code&gt;site:&lt;/code&gt; search operator to limit searches to subpages or subdomains of a single site or TLD. &lt;code&gt;site:.one&lt;/code&gt;, for instance, limits searches to websites with the &amp;ldquo;.one&amp;rdquo; TLD.&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;Matt from Gigablast told me that indexing YouTube or LinkedIn will get you blocked if you aren&amp;rsquo;t Google or Microsoft. I imagine that you could do so by getting special permission if you&amp;rsquo;re a megacorporation.&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Keeping platforms open</title>
      <link>https://envs.net/~seirdy/posts/2021/02/23/keeping-platforms-open/</link>
      <pubDate>Tue, 23 Feb 2021 19:54:00 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2021/02/23/keeping-platforms-open/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2021/02/23/keeping-platforms-open/">&lt;p&gt;This article is the second entry of series of posts exploring situations in which &lt;abbr title=&#34;free, libre, and open-source software&#34;&gt;FLOSS&lt;/abbr&gt; alone isn&amp;rsquo;t enough to secure user freedom.&lt;/p&gt;
&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p&gt;My previous article, &lt;a href=&#34;https://envs.net/~seirdy/2021/01/27/whatsapp-and-the-domestication-of-users/&#34;&gt;Whatsapp and the domestication of users&lt;/a&gt;, got more attention than I was expecting. Some responses gave me a lot to think about,&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; especially regarding &lt;em&gt;actions&lt;/em&gt; we can take. I suggest reading that article first; it explained what &amp;ldquo;user domestication&amp;rdquo; is and why it&amp;rsquo;s a problem. It enumerated three countermeasures: FLOSS, simplicity, and open platforms.&lt;/p&gt;
&lt;p&gt;Hard problems, by definition, lack easy solutions. Simply choosing (or creating) a platform that avoids user domestication isn&amp;rsquo;t enough if that platform can change. The price of freedom is eternal vigilance; in addition to settling on the right platform, we must ensure that it honors its users in both the present &lt;em&gt;and the future&lt;/em&gt;. Keeping a platform FLOSS and simple is more straightforward&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; than keeping a platform &amp;ldquo;open&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;How do we keep an open platform from becoming a closed platform in the future?&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;how-open-platforms-become-closed&#34;&gt;How open platforms become closed&lt;/h2&gt;
&lt;p&gt;There are three ways to close an open platform:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A forced migration onto a different platform.&lt;/li&gt;
&lt;li&gt;A single implementation growing dominant, blurring the line between specification and implementation.&lt;/li&gt;
&lt;li&gt;Dominant implementations adopting too many unstandardized features and behaviors.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These three approaches overlap: they frequently feature platform monoculture and a single vendor controlling both clients and servers.&lt;/p&gt;
&lt;h3 id=&#34;forced-migration&#34;&gt;Forced migration&lt;/h3&gt;
&lt;p&gt;A &lt;dfn id=&#34;boxed-platform&#34;&gt;boxed platform&lt;/dfn&gt; is a subset of a larger open platform that can evolve at its own pace, without concern for compatibility or interoperability.&lt;/p&gt;
&lt;p&gt;When one vendor controls all parts of a service (e.g., both a client and server), it has the means to create a boxed platform. Controlling both the server and client allows a vendor to update the client and server without worrying about breaking compatibility with other clients/servers in the larger network. It could update the client to point users to a server that uses a completely different, closed protocol. This is what happened to many XMPP users in the early 2000s.&lt;/p&gt;
&lt;h4 id=&#34;case-study-the-boxing-of-xmpp&#34;&gt;Case study: the boxing of XMPP&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/XMPP&#34;&gt;XMPP&lt;/a&gt; (formerly known as Jabber) is an open and federated instant-messaging protocol; anybody can set up their own XMPP server and talk to users on different XMPP servers, preventing one organization from owning the platform. Between 2005 and 2014, many proprietary chat platforms supported it: Google Talk, AOL Instant Messenger (AIM), Facebook Chat (later known as Facebook Messenger), and Skype were some well-known examples. Some of these platforms even enabled server-to-server federation.&lt;/p&gt;
&lt;p&gt;Unfortunately, users of these proprietary services were boxed. Not many Google Talk users talked to Skype users, and Skype users didn&amp;rsquo;t typically talk to AIM users. Users stayed in their own sub-platforms. The result was that all users limited themselves to talking exclusively using their provider&amp;rsquo;s software: one provider controlled the entire messaging flow, from a sender&amp;rsquo;s client to the server to a recipient&amp;rsquo;s client. &lt;strong&gt;Users were only ever exposed to a single XMPP implementation offered by a single provider.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Each of the listed platforms eventually locked in their users by migrating away from XMPP. This wouldn&amp;rsquo;t have been possible if multiple implementations and providers interacted with each other. Imagine Bob uses BobClient and BobServer to talk to Alice, and Alice uses AliceClient and AliceServer. BobClient, BobServer, AliceClient, and AliceServer would all have to remain compatible and use the same protocol; a forced migration would be unlikely to occur since it would break compatibility.&lt;/p&gt;
&lt;p&gt;Compare the situation with email: despite Gmail&amp;rsquo;s dominance, other email providers remain popular. Gmail users need to be able to communicate with non-Gmail users, and vice versa. Email is far less &amp;ldquo;boxed&amp;rdquo; than the aforementioned proprietary XMPP platforms. As a result, Google hasn&amp;rsquo;t been able to control the email platform as easily; Google can&amp;rsquo;t simply migrate Gmail users to a non-email platform that&amp;rsquo;s incompatible with the rest of the email landscape to further domesticate its users.&lt;/p&gt;
&lt;p&gt;XMPP is still alive and well, but its current popularity is a fraction of what it once was.&lt;/p&gt;
&lt;h3 id=&#34;implementation-clout&#34;&gt;Implementation clout&lt;/h3&gt;
&lt;p&gt;Standards are a form of agreements made to ensure compatibility between implementations. Such agreements need to be agreed upon by the implementations themselves. When one implementation grows dominant, so too does its leverage in the decision-making process over shared standards. Too much dominance can create a monoculture in which the dominant implementation is the only implementation that conforms to the spec.&lt;/p&gt;
&lt;p&gt;With enough leverage, a dominant implementation can serve as a reference implementation. Reference implementations are typically quite helpful, serving as a source of truth to test other implementations against. Problems may arise when development of the spec and production-grade reference implementation grow tightly coupled, leaving third-party implementation feasibility out of the decision-making process.&lt;/p&gt;
&lt;h4 id=&#34;case-study-matrix-and-element&#34;&gt;Case study: Matrix and Element&lt;/h4&gt;
&lt;p&gt;One example of this phenomenon is &lt;a href=&#34;https://matrix.org/&#34;&gt;Matrix&lt;/a&gt;. Matrix is an open and federated instant-messaging platform similar to XMPP, with a very large spec boasting many features: server-side history, replies, rich text, reactions, room versions, &lt;abbr title=&#34;end-to-end encryption&#34;&gt;E2EE&lt;/abbr&gt;, avatars, display names, typing indicators, read receipts, device verification&amp;hellip;the list goes on and grows every month.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; The only client that implements all the necessary features is Element. In addition to being the most popular client, Element practically serves as the reference client implementation: it&amp;rsquo;s developed by the same company that builds the dominant servers and most of the spec. The tight coupling between Element and the Matrix spec allow it to add features at a rate too fast for other clients too keep up; pretty much every Matrix user has to open up Element at some point to perform an action that isn&amp;rsquo;t supported in any other client. On the server side, Synapse is the only server that implements enough of the spec to be usable, with Dendrite coming in second. Both are made by the same company that develops Element.&lt;/p&gt;
&lt;p&gt;Since there aren&amp;rsquo;t any third-party clients and servers that can replace the official ones, one vendor is close to controlling all parts of the platform. The growing complexity required of clients and servers can also further entrench these dominant implementations, as I &lt;a href=&#34;https://envs.net/~seirdy/2021/01/27/whatsapp-and-the-domestication-of-users/#simplicity&#34;&gt;previously explained&lt;/a&gt;. Matrix is close to being a boxed platform because the official client and server can iterate independently of the greater ecosystem.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think that Matrix is going to become a fully closed platform anytime soon; the blog post &lt;a href=&#34;https://matrix.org/blog/2020/01/02/on-privacy-versus-freedom/&#34;&gt;&amp;ldquo;On Privacy versus Freedom&amp;rdquo;&lt;/a&gt; seems to put it on the right side of the closed/open spectrum. Clients like &lt;a href=&#34;https://github.com/tulir/gomuks&#34;&gt;gomuks&lt;/a&gt; and &lt;a href=&#34;https://fluffychat.im/&#34;&gt;FluffyChat&lt;/a&gt; seem to keep up with Element well enough to serve as partial replacements. I do, however, find its current state problematic and much closer to &amp;ldquo;closed&amp;rdquo; on the closed/open spectrum than XMPP, IRC, and email.&lt;/p&gt;
&lt;h3 id=&#34;unstandardized-feature-creep&#34;&gt;Un­standardized feature creep&lt;/h3&gt;
&lt;p&gt;Platforms are more than their protocols. Different implementations have unique behavior to distinguish themselves. Problems arise when dominant implementations&amp;rsquo; unique unstandardized features grow past a certain point to make a closed superset of an open platform.&lt;/p&gt;
&lt;h4 id=&#34;case-studies-email-providers&#34;&gt;Case studies: email providers&lt;/h4&gt;
&lt;p&gt;After reading my previous article, a few people contacted me to ask for my thoughts regarding certain email providers. There&amp;rsquo;s not much that can set a standard email provider apart if it just hosts a simple email server. To distinguish themselves, email providers often implement many features beyond email standards compliance.&lt;/p&gt;
&lt;p&gt;The vast majority of email accounts come from a small handful of dominant providers backed by large companies (Gmail, Yahoo! Mail, Yandex Mail, Mail.ru, iCloud, and others). Providers such as Gmail are notorious for implementing advanced spam filters prejudiced against non-mainstream email providers. Users who self-host email servers or use small providers frequently trigger false positives and end up having their messages incorrectly labeled as spam until they can build up a &amp;ldquo;reputation&amp;rdquo;.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; The addition of such a complex spam-prevention filter strengthens the email oligopoly by creating a barrier to entry for newcomers. Low-volume senders are discriminated against, as Migadu found out:&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;We&amp;rsquo;ve already seen our share of bad spam filters and misconfigured servers. In some cases recipient servers intentionally rejected correct emails just because we are a low volume sender. Ironically that is how an ideal sender should be. To improve the &amp;ldquo;receiveability&amp;rdquo; they of course offer their own hosted email service at a hefty price.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://archive.is/rJnSs#deliverability&#34;&gt;How&#39;s Migadu&#39;s Deliverability?&lt;/a&gt;&lt;/cite&gt;, section &amp;ldquo;So, Finally, How’s The Deliverability?&amp;rdquo;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Another example: email providers such as Hey.com, Protonmail, and Tutanota offer many features that are incompatible with IMAP/POP3. Protonmail and Tutanota use their own non-standard E2EE implementation (rather than focusing on improving the UX for vanilla PGP), and Hey.com offers server-side mail organization. Users of these services must use official Web, desktop, and mobile clients.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; These three providers control both the client and the server, giving them the means for vendor lock-in. Of course, there&amp;rsquo;s a limit to the amount of lock-in these providers can achieve: as I explained in the &lt;a href=&#34;#case-study-the-boxing-of-xmpp&#34;&gt;XMPP case study&lt;/a&gt;, these providers still need to support SMTP to stay compatible with the wider email landscape.&lt;/p&gt;
&lt;h2 id=&#34;solutions&#34;&gt;Solutions&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s enough doom-and-gloom. Let&amp;rsquo;s focus on actions that users and vendors can take to keep platforms open.&lt;/p&gt;
&lt;h3 id=&#34;what-users-can-do&#34;&gt;What users can do&lt;/h3&gt;
&lt;p&gt;As a user, consider using clients and servers made by different groups of people to make platform boxing more difficult. Pick implementations that suffer from less &lt;a href=&#34;https://en.wikipedia.org/wiki/Feature_creep&#34;&gt;feature creep&lt;/a&gt; beyond spec compliance. What distinguishes a client shouldn&amp;rsquo;t be &lt;em&gt;what&lt;/em&gt; features it has, but &lt;em&gt;how&lt;/em&gt; it implements its features. Obviously, having some unique features is great; problems arise when the number of unique features crosses a certain threshold. Following both these practices encourages implementations to stick to standards compliance, reliability, and compatibility rather than &amp;ldquo;innovation&amp;rdquo;. &lt;a href=&#34;https://web.archive.org/web/20210810063956/http://boringtechnology.club/&#34;&gt;Choose boring technology&lt;/a&gt; over shiny new features.&lt;/p&gt;
&lt;p&gt;Try venturing outside the mainstream by taking a look at a less popular provider or client. All implementations start somewhere, and a diversity of implementations prevents a rule by oligopoly.&lt;/p&gt;
&lt;p&gt;When picking a client and provider, consider the provider&amp;rsquo;s incentives. Who do your vendors serve? Do they serve users or investors? Have they scaled past the point of financial sustainability?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not arguing that average users are doing something &amp;ldquo;wrong&amp;rdquo; by doing otherwise; expecting average users to change their behavior for the greater good is naive. This advice is targeted at the subset of users technical and willing enough to put some thought into the platforms they choose, and indirectly targeted towards the people they can influence.&lt;/p&gt;
&lt;h3 id=&#34;what-vendors-can-do&#34;&gt;What vendors can do&lt;/h3&gt;
&lt;p&gt;Rather than focusing too much on scaling, focus on making server-side software easy to install and federate. Close sign-ups if your instance grows too big, and encourage people to check out different providers. Many Fediverse instances already practice this. I&amp;rsquo;m not saying that scaling is unimportant; rather, I&amp;rsquo;m saying that decreasing the barrier to entry for new providers is an effective alternate approach to scaling.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Consider copyleft licensing. Copyleft is one of the most powerful tools we have to protect user freedom by preventing the creation of derivative works that seek to restrict user freedom. This makes it more difficult for alternative implementations to keep changes to themselves in an effort to &amp;ldquo;box&amp;rdquo; users. The &lt;a href=&#34;https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License&#34;&gt;GNU &lt;abbr title=&#34;Affero General Public License, version 3&#34;&gt;AGPLv3&lt;/abbr&gt;&lt;/a&gt; is particularly effective since it requires distribution of server-side code for networked services; a viral proliferation of AGPLv3-licensed software could have mitigated the boxing of XMPP users in the early 2000s.&lt;/p&gt;
&lt;p&gt;Reference implementations are fine if they aren&amp;rsquo;t too dominant. Make sure that other implementations can catch up. If necessary, slow down the evolution of a spec, let developers of other implementations participate in the decision-making process, and lend them a hand to improve their implementations. Moving fast and breaking things isn&amp;rsquo;t the best approach.&lt;/p&gt;
&lt;p&gt;For example, Element and the Matrix.org Foundation would alleviate most of my concerns by doing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wind down new sign-ups on the matrix.org homeserver, pointing users to alternative servers run by different people instead.&lt;/li&gt;
&lt;li&gt;Adopt a very conservative approach to new features until more server- and client- implementations reach parity with Element, Synapse, and Dendrite.&lt;/li&gt;
&lt;li&gt;Focus on reducing the system requirements to host a server, reducing the barrier to entry for new providers. This is already underway with the development of Dendrite.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;drawbacks&#34;&gt;Drawbacks&lt;/h2&gt;
&lt;p&gt;The biggest drawback to the advice I&amp;rsquo;ve presented is development speed. Keeping compatibility and spec compliance slows down the rate at which new features can be added. &lt;a href=&#34;https://signal.org/blog/the-ecosystem-is-moving/&#34;&gt;As Moxie argues&lt;/a&gt;, Signal might not have been able to implement as many features if it was an open platform; spec-constrained development is, by definition, &lt;em&gt;constrained&lt;/em&gt;. Users are limited by the lowest common denominator among popular participating implementations.&lt;/p&gt;
&lt;p&gt;Open platforms with multiple providers and implementations often suffer from poorer usability, especially with regards to onboarding. Instead of just opening the official app/website, users need to choose from multiple clients and providers. This can be a turn-off for casual users just wanting to try something out. One of the best ways to improve the onboarding experience is to offer recommendations to your non-technical friends; you know them well and can probably help them make an informed decision.&lt;/p&gt;
&lt;h2 id=&#34;parallels-to-other-situations&#34;&gt;Parallels to other situations&lt;/h2&gt;
&lt;p&gt;Programming languages driven by a standard rather than a reference implementation typically have greater portability, many good implementations, and are unlikely to fade away with time. Examples include C, C++, Common Lisp, JavaScript, and POSIX Shell. Compare this with a language like Python: so many packages depend on the CPython reference implementation&amp;rsquo;s approach to C extensions that alternative implementations such as PyPy must perpetually remain second-class citizens.&lt;/p&gt;
&lt;p&gt;The standards- and consensus-driven approach to platform development and the inefficiency that comes with it is a trade-off visible in many places outside software development. Most forms of democracy suffer from bureaucracy and in-fighting that stifle progress. Some have argued that democracy&amp;rsquo;s inefficiency is a feature, not a bug. As Nathan Myhrvold puts it:&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;The reason societies with democratic governments are better places to live in than their alternatives isn’t because of some goodness intrinsic to democracy, but because its hopeless inefficiency helps blunt the basic potential for evil. The constraint of maintaining constant popularity is simply too large a burden to bear. So, happily, very little gets done that is extremely bad–or extremely good.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.nathanmyhrvold.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Nathan&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Myhrvold&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://slate.com/news-and-politics/1996/10/the-virtue-of-inefficient-government.html&#34;&gt;The Virtue of Inefficient Government&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Perhaps the biggest benefit to abandoning the &amp;ldquo;move fast and break things&amp;rdquo; mindset is that in addition to making it hard to rapidly improve a service, abandoning the mindset also makes it hard to rapidly worsen a service.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Ac­knowledge­ments&lt;/h2&gt;
&lt;p&gt;&lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://ossguy.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Denver&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Gingerich&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; helped me brainstorm early in the writing process and provided useful information for the section about XMPP.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://bzsombor.web.elte.hu/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Barna&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Zsombor&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; and carbolymer for giving good feedback over IRC.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://news.ycombinator.com/item?id=25961895&#34;&gt;This Hacker News comment&lt;/a&gt; in particular planted quite a few seeds for this article.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Please note that the words &amp;ldquo;straightforward&amp;rdquo; and &amp;ldquo;easy&amp;rdquo; are not interchangeable, though they do have some overlap.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://matrix.org/blog/category/this-week-in-matrix&#34;&gt;This Week in Matrix&lt;/a&gt;, a weekly blog of updates to the Matrix landscape. In particular, see the spec updates: new MSCs get merged every month.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;The official advice &lt;a href=&#34;https://support.google.com/mail/answer/81126&#34;&gt;from Google&lt;/a&gt; and &lt;a href=&#34;https://docs.aws.amazon.com/ses/latest/DeveloperGuide/dedicated-ip.html#dedicated-ips-managed-reputation&#34;&gt;AWS&lt;/a&gt; describes this behavior in more detail.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Protonmail offers its own &amp;ldquo;bridge&amp;rdquo; program which &amp;ldquo;translates&amp;rdquo; the Protonmail API into IMAP, allowing users to use their preferred mail clients. This still doesn&amp;rsquo;t change the fact that users must use official clients; in this case, the official client is the bridge program itself.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;I decided against using the cheeky sub-heading &amp;ldquo;Scaling considered harmful&amp;rdquo; because I worried that readers on a certain orange-colored website might take the joke too seriously.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>WhatsApp and the domestication of users</title>
      <link>https://envs.net/~seirdy/posts/2021/01/27/whatsapp-and-the-domestication-of-users/</link>
      <pubDate>Thu, 28 Jan 2021 00:13:36 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2021/01/27/whatsapp-and-the-domestication-of-users/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2021/01/27/whatsapp-and-the-domestication-of-users/">&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p role=&#34;note&#34;&gt;
&lt;em&gt;Update: I wrote a follow up: &lt;a href=&#34;../../../../2021/02/23/keeping-platforms-open/&#34;&gt;Keeping platforms open&lt;/a&gt;. Check it out if you found this article interesting.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
I have never used WhatsApp, and never will. Despite this, I still feel the need to write an article about WhatsApp since it’s the perfect case study to help understand a class of businesses models I call “user domestication”. The domestication of users is high on my list of problems plaguing the human race, and is worth a detailed explanation.
&lt;/p&gt;
&lt;p&gt;WhatsApp wasn&amp;rsquo;t the first instant messenger of its kind, and probably won&amp;rsquo;t be the last. I simply chose to focus on WhatsApp since its recent privacy issues have made it a hot topic.&lt;/p&gt;
&lt;p&gt;With the meta-explanation out of the way, let us begin.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;whatsapps-rise&#34;&gt;WhatsApp&amp;rsquo;s rise&lt;/h2&gt;
&lt;p&gt;For those unfamiliar, WhatsApp is a tool that makes it convenient and easy to help Facebook further its core mission: the optimization and auctioning of human behavior (colloquially known as &amp;ldquo;targeted advertising&amp;rdquo;). It originally persuaded people to consent to this by allowing them to send text to each other over the Internet, something that was &lt;a href=&#34;https://en.wikipedia.org/wiki/Comparison_of_instant_messaging_protocols&#34;&gt;already possible&lt;/a&gt;, and combining an easy-to-learn UI with successful marketing. It then expanded to include features such as free voice and video calls. Free calls helped it grow to become the de-facto communication platform in many regions. I&amp;rsquo;m stunned at its ubiquity every time I visit my extended family in India; I&amp;rsquo;m frequently greeted by looks of confusion when I remind them that I don&amp;rsquo;t use WhatsApp.&lt;/p&gt;
&lt;p&gt;Having its own proprietary chat system incompatible with other clients allowed WhatsApp to build a &lt;a href=&#34;https://en.wikipedia.org/wiki/Network_effect&#34;&gt;network effect&lt;/a&gt;: WhatsApp&amp;rsquo;s existing users were held captive by the fact that leaving WhatsApp meant losing the ability to communicate with WhatsApp users. People switching from WhatsApp must convince all their friends to switch, too; this includes less technically inclined friends who had a hard time learning WhatsApp in the first place.&lt;/p&gt;
&lt;p&gt;In a WhatsApp world, people who want to keep in touch must abide by the following rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Everyone can only use the proprietary WhatsApp client to send messages; developing alternative clients isn&amp;rsquo;t supported.&lt;/li&gt;
&lt;li&gt;Everyone&amp;rsquo;s mobile device must run an operating system supported by said client. Since WhatsApp developers will only write a client for popular operating systems, the Android and iOS duopoly strengthens.&lt;/li&gt;
&lt;li&gt;Users fully depend on WhatsApp developers. If WhatsApp developers decide to include user-hostile features in the app, users must go with it. They can&amp;rsquo;t switch to a different server or client without switching away from WhatsApp and losing the ability to communicate with all their WhatsApp contacts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;user-domestication&#34;&gt;User domestication&lt;/h2&gt;
&lt;p&gt;WhatsApp rose by trapping previously-free beings in their corral and changing their habits to create dependence on masters. Over time, this made it difficult or impossible to return to their previous lifestyle. That process should sound familiar: it&amp;rsquo;s eerily similar to the domestication of animals.&lt;/p&gt;
&lt;p&gt;I call this type of vendor lock-in &lt;dfn id=&#34;user-domestication-dfn&#34;&gt;user domestication&lt;/dfn&gt;: the removal of user autonomy to trap users into serving vendors.&lt;/p&gt;
&lt;p&gt;I chose this metaphor because animal domestication is a gradual process that isn&amp;rsquo;t always deliberate, and typically revolves around one group becoming dependent upon another. For example: there&amp;rsquo;s evidence that domestication of dogs began with socialization, resulting in not-entirely-artificial selection promoting genes that resulted in more friendliness with and dependence upon humans.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Whether it happens on purpose or by accident, user domestication almost always follows the same three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A high level of dependence given from users to a software vendor&lt;/li&gt;
&lt;li&gt;An inability for users to control their software, through at least one of the following methods:
&lt;ol&gt;
&lt;li&gt;Preventing modification of the software&lt;/li&gt;
&lt;li&gt;Preventing migration onto a different platform&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;The exploitation of now-captive users who are unable to resist&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The completion of the first two steps left WhatsApp users vulnerable to user domestication. With investors to answer to, they had every incentive to implement user-hostile features without consequence.&lt;/p&gt;
&lt;p&gt;So, of course, they did.&lt;/p&gt;
&lt;h2 id=&#34;whatsapps-descent&#34;&gt;WhatsApp&amp;rsquo;s descent&lt;/h2&gt;
&lt;p&gt;Domestication has a purpose: it enables a master species to exploit the domesticated species for its own gain.&lt;/p&gt;
&lt;p&gt;Recently, WhatsApp updated its privacy policy to allow sharing data with its parent, Facebook. Users who agreed to use WhatsApp under its previous privacy policy had two options: agree to the new policy or be unable to use WhatsApp again. The WhatsApp privacy policy update is a classic bait-and-switch: WhatsApp lured users in with a sleek interface and the impression of privacy, domesticated them to remove their autonomy to migrate, and then backtracked on its previous commitment to privacy with minimal consequence. Each step in this process enabled the next; had user domestication not taken place, it would be easy for most users to switch away with minimal friction.&lt;/p&gt;
&lt;p&gt;Those of us who were sounding the alarm a few years ago experienced a brief moment of sadistic bliss when our titles were upgraded from &amp;ldquo;annoying and paranoid conspiracy theorists&amp;rdquo; to just &amp;ldquo;annoying&amp;rdquo;.&lt;/p&gt;
&lt;h3 id=&#34;an-attempt-at-damage-control&#34;&gt;An attempt at damage control&lt;/h3&gt;
&lt;p&gt;The bait-and-switch operation incurred backlash significant enough for a noticeable minority of users to actually migrate; this number turned out to be slightly more than the rounding error WhatsApp was likely expecting. In response, WhatsApp delayed the change and published an ad to improve its image.&lt;/p&gt;
&lt;hr /&gt;
&lt;section
	aria-label=&#34;image, caption, and transcript&#34;
	
	id=&#34;whatsapp-notice&#34; tabindex=&#34;-1&#34;&gt;
&lt;h4 id=&#34;whatsapp-notice-hd&#34;&gt;&lt;span&gt;Whatsapp Ad&lt;/span&gt;&lt;/h4&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/whatsapp_ad_dark.1020619168.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/whatsapp_ad_dark.621143313.webp&#34;
type=&#34;image/webp&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/whatsapp_ad_dark.402539497.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/whatsapp_ad.1572520332.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/whatsapp_ad.4164128367.webp&#34;
type=&#34;image/webp&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/whatsapp_ad.287011306.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;600&#34; height=&#34;600&#34;
src=&#34;https://envs.net/~seirdy/p/whatsapp_ad.287011306.png&#34; alt=&#34;WhatsApp notice describing data not collected.&#34;
aria-describedby=&#34;transcript-whatsapp-notice&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;WhatsApp ad, taken from &lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://faq.whatsapp.com/general/security-and-privacy/answering-your-questions-about-whatsapps-privacy-policy&#34;&gt;Answering your questions about WhatsApp’s Privacy Policy&lt;/a&gt;&lt;/cite&gt; (archived: &lt;a href=&#34;https://web.archive.org/web/20210121163337/https://faq.whatsapp.com/general/security-and-privacy/answering-your-questions-about-whatsapps-privacy-policy&#34;&gt;Wayback Machine &lt;time datetime=&#34;2021-01-21T16:33:37+00:00&#34;&gt;2021-01-21&lt;/time&gt; snapshot&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;details&gt;
&lt;summary&gt;Toggle image &lt;span&gt;transcript&lt;/span&gt;&lt;/summary&gt;
&lt;section id=&#34;transcript-whatsapp-notice&#34;&gt;
&lt;h5&gt;Image transcript&lt;/h5&gt;
	&lt;div&gt;
		&lt;p&gt;WhatsApp Protects and Secures Your Personal Messages.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;WhatsApp cannot see your personal messages or hear your calls and neither can Facebook.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WhatsApp does not keep logs of who everyone is messaging or calling.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WhatsApp cannot see your shared location and neither can Facebook.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WhatsApp does not share your contacts with Facebook.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WhatsApp groups remain private.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can set your messages to disappear.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can download your data.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/details&gt;

&lt;/section&gt;
&lt;hr /&gt;

&lt;p&gt;The ad lists various data that WhatsApp doesn&amp;rsquo;t collect or share. Allaying data collection concerns by listing data &lt;em&gt;not&lt;/em&gt; collected is misleading. WhatsApp doesn&amp;rsquo;t collect hair samples or retinal scans either; not collecting that information doesn&amp;rsquo;t mean it respects privacy because it doesn&amp;rsquo;t change the information WhatsApp &lt;em&gt;does&lt;/em&gt; collect.&lt;/p&gt;
&lt;p&gt;The ad denies &amp;ldquo;keep[ing] logs of who everyone is messaging or calling&amp;rdquo;. Collecting data is not the same as &amp;ldquo;keeping logs&amp;rdquo;; it&amp;rsquo;s possible for metadata to be fed into an algorithm before being discarded. A model can thus learn that two users call each other frequently without keeping logs of the metadata for each call. The fact that they specifically chose to phrase this line around logging implies that WhatsApp either already collects this class of data or has deliberately left the door open to collecting it in the future.&lt;/p&gt;
&lt;p&gt;A stroll through WhatsApp&amp;rsquo;s &lt;a href=&#34;https://web.archive.org/web/20210124061525/https://www.whatsapp.com/legal/updates/privacy-policy/?lang=en&#34;&gt;actual privacy policy&lt;/a&gt; at the time reveals that they do collect considerable metadata used for marketing through Facebook.&lt;/p&gt;
&lt;h2 id=&#34;software-freedom&#34;&gt;Software freedom&lt;/h2&gt;
&lt;p&gt;With user domestication, providing useful software to users is a means to the end of exploiting them. The alternative is simple: make serving users the end in and of itself.&lt;/p&gt;
&lt;p&gt;To avoid being controlled by software, users must be in control. Software that allows users to be in control is called &lt;a href=&#34;https://en.wikipedia.org/wiki/Free_software&#34;&gt;free software&lt;/a&gt; or libre software. The word &amp;ldquo;free&amp;rdquo; in this context refers to freedom rather than price. Software freedom is similar to the concept of open-source; the latter is an offshoot of the former focused on more business-friendly practical benefits rather than ethics. A less ambiguous term that neutrally refers to free, libre, and open-source software is &lt;strong&gt;&lt;abbr title=&#34;free, libre, and open-source software&#34;&gt;FLOSS&lt;/abbr&gt;&lt;/strong&gt;.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Others have explained the &lt;a href=&#34;https://www.gnu.org/philosophy/free-sw.en.html&#34;&gt;fundamental concepts&lt;/a&gt; underpinning free software and &lt;a href=&#34;https://www.gnu.org/philosophy/free-software-even-more-important.html&#34;&gt;its importance&lt;/a&gt; better than I can, so I won&amp;rsquo;t go into detail. It comes down to four essential freedoms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The freedom to run the program as you wish, for any purpose&lt;/li&gt;
&lt;li&gt;The freedom to study how the program works, and change it so it does your computing as you wish&lt;/li&gt;
&lt;li&gt;The freedom to redistribute copies so you can help others&lt;/li&gt;
&lt;li&gt;The freedom to distribute copies of your modified versions to others&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;making-money-with-floss&#34;&gt;Making money with FLOSS&lt;/h3&gt;
&lt;p&gt;The most common objection I hear is that FLOSS makes it harder to make money.&lt;/p&gt;
&lt;p&gt;The key to making money with FLOSS is to make software a &lt;a href=&#34;https://www.gwern.net/Complement&#34;&gt;commoditized complement&lt;/a&gt; of other, more profitable services. Examples of such services include selling support, customization, consulting, training, managed hosting, hardware, and certifications. Plenty of companies use this approach instead of building proprietary software: Red Hat, Collabora, System76, Purism, Canonical, SUSE, Hashicorp, Databricks, and Gradle are some names that come to mind.&lt;/p&gt;
&lt;p&gt;Managed hosting isn&amp;rsquo;t a basket worth all your eggs if giants like AWS can do the same at a lower price. Being the developer can give an edge in areas like customization, support, and training; it doesn&amp;rsquo;t offer as obvious an advantage when it comes to hosting.&lt;/p&gt;
&lt;h2 id=&#34;floss-isnt-always-enough&#34;&gt;FLOSS isn&amp;rsquo;t always enough&lt;/h2&gt;
&lt;p&gt;Free software is a necessary but sometimes insufficient requirement to build domestication immunity. Two more measures include &lt;strong&gt;simplicity&lt;/strong&gt; and &lt;strong&gt;open platforms.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;simplicity&#34;&gt;Simplicity&lt;/h3&gt;
&lt;p&gt;When software grows too complex, it needs to be maintained by a large team. Users who disagree with a vendor can&amp;rsquo;t easily fork and maintain a multi-million-line codebase, especially if the software in question potentially contains security vulnerabilities. Dependence on the vendor can grow quite problematic when complexity causes development costs to skyrocket; the vendor might resort to implementing user-hostile features to stay afloat.&lt;/p&gt;
&lt;p&gt;Complex software that can&amp;rsquo;t be developed by a different group of people creates dependence, step one of user domestication. That alone is enough to open the door to problematic developments.&lt;/p&gt;
&lt;h4 id=&#34;case-study-mozilla-and-the-web&#34;&gt;Case study: Mozilla and the Web&lt;/h4&gt;
&lt;p&gt;Mozilla was a ray of hope in the browser wars, a space dominated by adtech, surveillance, and vendor lock-in. Unfortunately, developing a browser engine is a monumental task difficult enough for Opera and Microsoft to give up and re-skin Chromium. Browsers are more than the document readers they were meant to be: they&amp;rsquo;ve evolved into application runtimes with their own stacks for GPU acceleration, Bluetooth, permissions, device enumeration, bundled media codecs, &lt;abbr title=&#34;digital rights management&#34;&gt;DRM&lt;/abbr&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, extension APIs, developer tools&amp;hellip;the list goes on. It takes billions of dollars a year to respond to vulnerabilities in such a massive attack surface and keep up with a standard that grows at such a worrying rate. Those billions have to come from somewhere.&lt;/p&gt;
&lt;p&gt;Mozilla ended up having to make major compromises to stay afloat. It cut search deals with blatantly user-hostile companies, and bundled the browser with &lt;a href=&#34;https://blog.mozilla.org/advancingcontent/2014/02/11/publisher-transformation-with-users-at-the-center/&#34;&gt;ads&lt;/a&gt; and bloatware such as a partially ad-funded proprietary bookmarking SaaS called &lt;a href=&#34;https://dustri.org/b/firefox-youre-supposed-to-be-in-my-pocket-not-the-other-way-around.html&#34;&gt;Pocket&lt;/a&gt;. Since acquiring Pocket (to diversify its sources of income), Mozilla hasn&amp;rsquo;t yet delivered on its &lt;a href=&#34;https://techcrunch.com/2017/02/27/mozilla-pockets-pocket-in-first-acquisition/&#34;&gt;earlier statements&lt;/a&gt; saying it would open-source its code: while the clients have been open-sourced, the server code remains proprietary. Open-sourcing this and re-writing portions if necessary would understandably be a large task due in part to Pocket&amp;rsquo;s complexity.&lt;/p&gt;
&lt;p&gt;Substantial forks such as Pale Moon are unable to keep up with the growing complexity of modern Web standards such as Web Components. In fact, Pale Moon recently had to &lt;a href=&#34;https://forum.palemoon.org/viewtopic.php?f=1&amp;amp;t=25473&#34;&gt;migrate its code off of GitHub&lt;/a&gt; since GitHub began using Web Components, a feature too complex for Pale Moon to support. It&amp;rsquo;s nigh-impossible to start a new browser from scratch and catch up with behemoths that have been running on ridiculous annual sums for decades. Users can pick between a browser engine developed by Mozilla, an adtech company (Blink by Google), or a walled-garden vendor (WebKit by Apple). WebKit doesn&amp;rsquo;t seem too bad, but users will be helpless if Apple ever decides to backtrack.&lt;/p&gt;
&lt;p&gt;To summarize: the complexity of the Web platform forced Mozilla, the only browser engine developer claiming to serve &amp;ldquo;people, not profit&amp;rdquo;, to implement user-hostile features in its browser. The Web&amp;rsquo;s complexity has left users with limited choice between three big players with conflicts of interest whose positions grow more entrenched with time.&lt;/p&gt;
&lt;p&gt;For the record, &lt;strong&gt;I don&amp;rsquo;t think Mozilla is a bad organization;&lt;/strong&gt; rather, I think it&amp;rsquo;s surprising that they&amp;rsquo;re able to do so much without further compromise in a system that practically requires it. Their core product is still FLOSS, and very lightly patched third-party builds remove antifeatures.&lt;/p&gt;
&lt;h3 id=&#34;open-platforms&#34;&gt;Open platforms&lt;/h3&gt;
&lt;p&gt;To prevent a network effect from turning into vendor lock-in, software that naturally encourages a network effect needs to be part of an open platform. In the case of messaging software, it should be possible to make alternative clients and servers that are compatible with each other to prevent completion of user domestication&amp;rsquo;s first two steps.&lt;/p&gt;
&lt;h4 id=&#34;case-study-signal&#34;&gt;Case study: Signal&lt;/h4&gt;
&lt;p&gt;Ever since a certain car salesman &lt;a href=&#34;https://web.archive.org/web/20210108024414/https://nitter.net/elonmusk/status/1347165127036977153&#34;&gt;tweeted&lt;/a&gt; &amp;ldquo;Use Signal&amp;rdquo;, large numbers of users have been obediently switching. At the time of writing, the Signal clients and servers are FLOSS and use some of the best &lt;abbr title=&#34;end-to-end encryption&#34;&gt;E2EE&lt;/abbr&gt; out there; however, I&amp;rsquo;m not a fan.&lt;/p&gt;
&lt;p&gt;Although Signal&amp;rsquo;s clients and servers are FLOSS, Signal is still a closed platform. Signal co-founder Moxie Marlinspike is quite critical of open and federated platforms, describing his rationale for keeping Signal a closed platform in &lt;a href=&#34;https://signal.org/blog/the-ecosystem-is-moving/&#34;&gt;a blog post&lt;/a&gt;.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; This means that there&amp;rsquo;s no supported way to develop an alternative server that&amp;rsquo;s supported by Signal clients, or an alternative client that supports Signal servers. Step one to user domestication is nearly complete.&lt;/p&gt;
&lt;p&gt;In addition to there being a single client and server implementation, there&amp;rsquo;s only one Signal server provider: Signal Messenger LLC. Users&amp;rsquo; dependence on this central server provider blew up in their faces when Signal&amp;rsquo;s recent growth caused downtime for over a day, rendering every Signal user unable to send messages until the single vendor fixed the issue.&lt;/p&gt;
&lt;p&gt;People still tried to develop alternative clients: a Signal fork called &lt;a href=&#34;https://github.com/LibreSignal/LibreSignal&#34;&gt;LibreSignal&lt;/a&gt; attempted to make Signal work on privacy-friendly Android builds without proprietary Google Play Services. That fork shut down after Moxie &lt;a href=&#34;https://github.com/LibreSignal/LibreSignal/issues/37#issuecomment-217211165&#34;&gt;made it clear&lt;/a&gt; that he wasn&amp;rsquo;t okay with a third-party app using Signal&amp;rsquo;s servers. Moxie&amp;rsquo;s decision is understandable, but the situation could have been avoided if Signal didn&amp;rsquo;t have to rely on a single server provider.&lt;/p&gt;
&lt;p&gt;If Signal decides to update its apps to include a user-hostile feature, users will be just as helpless as they now are with WhatsApp. Although I don&amp;rsquo;t think this is likely, Signal&amp;rsquo;s closed platform leaves users vulnerable to user domestication.&lt;/p&gt;
&lt;p&gt;Despite not liking Signal, I still recommended it to my non-technical friends because it was the only messenger private enough for me and simple enough for them. If it had literally any onboarding (account creation, manually adding contacts, etc.), one of my friends would have stuck with Discord or WhatsApp. I&amp;rsquo;d say something cheeky like &amp;ldquo;you know who you are&amp;rdquo; if there was any chance he&amp;rsquo;d make it this far in the article.&lt;/p&gt;
&lt;h2 id=&#34;food-for-thought&#34;&gt;Food for thought&lt;/h2&gt;
&lt;p&gt;Both of the prior two case studies&amp;mdash;Mozilla and Signal&amp;mdash;are examples of well-meaning organizations unintentionally leaving users vulnerable to user domestication. The former represents a lack of simplicity but the presence of an open platform. The latter represents a closed platform with a higher degree of simplicity. Intent isn&amp;rsquo;t in the picture when examining the three steps and countermeasures to user domestication.&lt;/p&gt;
&lt;p&gt;paulsnar pointed out a potential conflict between simplicity and open platforms:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I feel like there&amp;rsquo;s some tension between simplicity and open platforms; to take Signal, in a way it&amp;rsquo;s simple precisely because it&amp;rsquo;s a de-facto-closed platform, or at least so Moxie has argued. In turn, Matrix is superficially simple, but the protocol is actually (imho) fairly complex exactly because it&amp;rsquo;s an open platform.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&amp;rsquo;t have a simple answer to this dilemma. It&amp;rsquo;s true that &lt;a href=&#34;https://matrix.org/&#34;&gt;Matrix&lt;/a&gt; is extremely complex (compared to alternatives such as IRC or even &lt;a href=&#34;https://xmpp.org/&#34;&gt;XMPP&lt;/a&gt;), and it&amp;rsquo;s true that it&amp;rsquo;s harder to build an open platform. That being said, it&amp;rsquo;s certainly possible to keep complexity on a leash while developing an open platform: Gemini, IRC, and email are examples. While email standards aren&amp;rsquo;t nearly simple as Gemini and IRC, they evolve slowly; this keeps implementations from having to play catch-up the way Web browsers and Matrix clients/servers do.&lt;/p&gt;
&lt;p&gt;Not all software needs to rake in billions. Federation &lt;a href=&#34;https://drewdevault.com/2020/09/20/The-potential-of-federation.html&#34;&gt;allows&lt;/a&gt; services and networks like the Fediverse and XMPP to scale up to large numbers of users without forcing a single behemoth to sell its soul to foot the bill. Although anti-domestication business models are less profitable, they still allow the creation of the same technologies that were enabled by user domestication. All that&amp;rsquo;s missing is an advertising budget; the biggest advertising some of these projects get is long unpaid blog posts.&lt;/p&gt;
&lt;p&gt;Maybe we don&amp;rsquo;t need to chase growth and try to &amp;ldquo;make it big&amp;rdquo;. Maybe we can stop after achieving sustainability and financial security, and make it possible for people to do more with less.&lt;/p&gt;
&lt;h2 id=&#34;closing-notes&#34;&gt;Closing notes&lt;/h2&gt;
&lt;p&gt;Before it turned into a manifesto of sorts, this post was intended to be an expanded version of a comment I left under a &lt;a href=&#34;https://fosstodon.org/@binyamin/105608407071699797&#34;&gt;Fediverse post&lt;/a&gt; by &lt;a href=&#34;https://binyam.in/&#34;&gt;Binyamin Green&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I initially decided to expand it to its current form for personal reasons. Nowadays, people demand a thorough explanation every time I refuse to use something that &amp;ldquo;everybody&amp;rdquo; uses (WhatsApp, Microsoft Office, Windows, macOS, Google Docs&amp;hellip;). They&amp;rsquo;ll usually ignore the explanation, but they expect one anyway. By the next time I meet them, they&amp;rsquo;ll have forgotten our prior conversation and will re-enact the same dialogue again. Justifying all my life choices by sending logically correct statements into the void&amp;mdash;knowing that everything I say will be ignored&amp;mdash;is an emotionally draining process that has taken a toll on my mental health for the past few years; sending my friends this article and changing the subject should save me a few gray hairs in the years to come.&lt;/p&gt;
&lt;p&gt;This article extends the guiding philosophies of the Free Software and Copyleft movements. Thanks to &lt;a href=&#34;https://bzsombor.web.elte.hu/&#34;&gt;Barna Zsombor&lt;/a&gt; for giving good feedback over IRC.&lt;/p&gt;
&lt;p&gt;Since 2900 words wasn&amp;rsquo;t quite enough, I wrote a follow-up: &lt;a href=&#34;https://envs.net/~seirdy/2021/02/23/keeping-platforms-open/&#34;&gt;Keeping platforms open&lt;/a&gt;. Check it out if you found this article interesting.&lt;/p&gt;
&lt;h2 id=&#34;translations&#34;&gt;Translations&lt;/h2&gt;
&lt;p&gt;Translations are always welcome.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://evgenykuznetsov.org/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Евгений&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Кузнецов&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; translated this article to &lt;span&gt;Russian&lt;/span&gt;: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://evgenykuznetsov.org/posts/2021/domestication/&#34; lang=&#34;ru&#34; hreflang=&#34;ru&#34; rel=&#34;alternate&#34;&gt;WhatsApp и одомашнивание пользователей&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;The Framalang translators at &lt;a href=&#34;https://framasoft.org/&#34;&gt;Framasoft&lt;/a&gt; translated this article to &lt;span&gt;French&lt;/span&gt;: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://framablog.org/2021/02/04/utilisateurs-libres-ou-domestiques-whatsapp-et-les-autres/&#34; lang=&#34;fr&#34; hreflang=&#34;fr&#34; rel=&#34;alternate&#34;&gt;WhatsApp et la domestication des utilisateurs&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://web.archive.org/web/20210924154338/https://convorb.im/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-nickname nickname&#34;&gt;Licaon Kter&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; translated this article to &lt;span&gt;Romanian&lt;/span&gt;: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://web.archive.org/web/20210924154306/convorb.im/post/2021/02/14/whatsapp-si-domesticirea-utilizatorilor.html&#34; lang=&#34;ro&#34; hreflang=&#34;ro&#34; rel=&#34;alternate&#34;&gt;WhatsApp și domesticirea utilizatorilo&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://sgfault.com&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;David&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Jimenez&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; translated this article to &lt;span&gt;Spanish&lt;/span&gt;: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://sgfault.com/post/2021/02/2021-02-21-whatsapp-y-la-domesticacion-de-usuarios/&#34; lang=&#34;es&#34; hreflang=&#34;es&#34; rel=&#34;alternate&#34;&gt;WhatsApp y la domesticación de usuario&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.lealternative.net/author/skariko/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-nickname nickname&#34;&gt;Skariko&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
from &lt;span class=&#34;p-org org&#34;&gt;
&lt;a class=&#34;organization-name&#34; href=&#34;https://lealternative.net/&#34;&gt;
&lt;span&gt;Le Alternative&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; translated this article to &lt;span&gt;Italian&lt;/span&gt;: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.lealternative.net/2021/12/13/whatsapp-e-laddomesticamento-degli-utenti/&#34; lang=&#34;it-IT&#34; hreflang=&#34;it-IT&#34; rel=&#34;alternate&#34;&gt;WhatsApp e l’addomesticamento degli utent&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://blog.puer-robustus.eu/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-nickname nickname&#34;&gt;puer robustus&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; translated this article to &lt;span&gt;German&lt;/span&gt;: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://blog.puer-robustus.eu/post/domestizierung-von-nutzern/&#34; lang=&#34;de-DE&#34; hreflang=&#34;de-DE&#34; rel=&#34;alternate&#34;&gt;WhatsApp und die Domestizierung von Nutzern&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;span&gt;Pierotti, R.; Fogg, B. (2017). The First Domestication: How Wolves and Humans Coevolved. Yale University Press.&lt;/span&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Many within the free software movement dislike the term &amp;ldquo;open source&amp;rdquo; for a &lt;a href=&#34;https://www.gnu.org/philosophy/open-source-misses-the-point.html&#34;&gt;number of reasons&lt;/a&gt;; others use the terms &amp;ldquo;free&amp;rdquo; and &amp;ldquo;open source&amp;rdquo; &lt;a href=&#34;https://drewdevault.com/2019/09/17/The-wrong-words-but-the-right-ideas.html&#34;&gt;interchangeably&lt;/a&gt;. Finally, many vendors use the word &amp;ldquo;free&amp;rdquo; to refer to price rather than freedom, prompting some free software supporters to adopt the term &amp;ldquo;libre&amp;rdquo; instead. All this can be quite confusing, which is why I prefer acronyms like FLOSS to describe these terms&amp;rsquo; intersection.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://www.defectivebydesign.org/&#34;&gt;Defective by Design&lt;/a&gt;. DRM is another classic example of user domestication. For the record, Mozilla opposed making DRM a Web standard. It implemented DRM support after it lost to the other W3C members. This doesn&amp;rsquo;t excuse putting DRM in a browser, but at least there wasn&amp;rsquo;t malicious intent. The same can&amp;rsquo;t be said for the pro-DRM members of the W3C.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Moxie&amp;rsquo;s blog post generated many responses. Two good follow-ups are on &lt;a href=&#34;https://lwn.net/Articles/687294/&#34;&gt;Linux Weekly News&lt;/a&gt; and a &lt;a href=&#34;https://matrix.org/blog/2020/01/02/on-privacy-versus-freedom/&#34;&gt;blog post&lt;/a&gt; by Matrix.org&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Becoming physically immune to brute-force attacks</title>
      <link>https://envs.net/~seirdy/posts/2021/01/12/password-strength/</link>
      <pubDate>Tue, 12 Jan 2021 08:03:10 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2021/01/12/password-strength/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2021/01/12/password-strength/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2 id=&#34;preface&#34;&gt;Preface&lt;/h2&gt;
&lt;p&gt;This is a tale of the intersection between thermal physics, cosmology, and a tiny amount of computer science to answer a seemingly innocuous question: &amp;ldquo;How strong does a password need to be for it to be physically impossible to brute-force, ever?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;#conclusion-tldr&#34;&gt;TLDR&lt;/a&gt; at the bottom.&lt;/p&gt;
&lt;div role=&#34;doc-tip&#34;&gt;
&lt;p&gt;&lt;em&gt;Note: this post contains equations. Since none of the equations were long or complex, I decided to just write them out in code blocks instead of using images or MathML the way Wikipedia does.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Update: I implemented the ideas in this blog post (and more) in a program/library, &lt;a href=&#34;https://sr.ht/~seirdy/MOAC/&#34;&gt;MOAC&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#introduction&#34;&gt;Intro­duction&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#asking-the-right-question&#34;&gt;Asking the right question&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#quantifying-password-strength&#34;&gt;Quantifying password strength.&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#the-problem&#34;&gt;The Problem&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#caveats-and-estimates&#34;&gt;Caveats and estimates&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#compushytation&#34;&gt;Compu­tation&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#calculating-the-mass-energy-of-the-observable-universe&#34;&gt;Calculating the mass-energy of the observable universe&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#calculating-the-critical-density-of-the-observable-universe&#34;&gt;Calculating the critical density of the observable universe&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#solving-for-e&#34;&gt;Solving for E&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#final-solution&#34;&gt;Final Solution&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#sample-unbreakable-passwords&#34;&gt;Sample unbreakable passwords&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#conclusion-tldr&#34;&gt;Conclusion, TLDR&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#further-reading-alternative-approaches&#34;&gt;Further reading: alternative approaches&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#approaches-that-account-for-computation-speed&#34;&gt;Approaches that account for computation speed&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#acknowledgements&#34;&gt;Ac­knowledge­ments&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p&gt;I realize that advice on password strength can get outdated. As supercomputers grow more powerful, password strength recommendations need to be updated to resist stronger brute-force attacks. Passwords that are strong today might be weak in the future. &lt;strong&gt;How long should a password be in order for it to be physically impossible to brute-force, ever?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This question might not be especially practical, but it&amp;rsquo;s fun to analyze and offers interesting perspective regarding sane upper-limits on password strength.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;asking-the-right-question&#34;&gt;Asking the right question&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s limit the scope of this article to passwords used in encryption/decryption. An attacker is trying to guess a password to decrypt something.&lt;/p&gt;
&lt;p&gt;Instead of predicting what tomorrow&amp;rsquo;s computers may be able to do, let&amp;rsquo;s examine the &lt;em&gt;biggest possible brute-force attack&lt;/em&gt; that the laws of physics can allow.&lt;/p&gt;
&lt;p&gt;A supercomputer is probably faster than your phone; however, given enough time, both are capable of doing the same calculations. If time isn&amp;rsquo;t the bottleneck, energy usage is. More efficient computers can flip more bits with a finite amount of energy.&lt;/p&gt;
&lt;p&gt;In other words, energy efficiency and energy availability are the two fundamental bottlenecks of computing. What happens when a computer with the highest theoretical energy efficiency is limited only by the mass-energy of &lt;em&gt;the entire &lt;a href=&#34;https://en.wikipedia.org/wiki/Observable_universe&#34;&gt;observable universe&lt;/a&gt;?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s call this absolute unit of an energy-efficient computer the MOAC (Mother of All Computers). For all classical computers that are made of matter, do work to compute, and are bound by the conservation of energy, the MOAC represents a finite yet unreachable limit of computational power. And yes, it can play Solitaire with &lt;em&gt;amazing&lt;/em&gt; framerates.&lt;/p&gt;
&lt;p&gt;How strong should your password be for it to be safe from a brute-force attack by the MOAC?&lt;/p&gt;
&lt;h3 id=&#34;quantifying-password-strength&#34;&gt;Quantifying password strength.&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;A previous version of this section wasn&amp;rsquo;t clear and accurate. I&amp;rsquo;ve since removed the offending bits and added a clarification about salting/hashing to the &lt;a href=&#34;#caveats-and-estimates&#34;&gt;Caveats and estimates&lt;/a&gt; section.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A good measure of password strength is &lt;strong&gt;entropy bits.&lt;/strong&gt; The entropy bits in a password is a base-2 logarithm of the number of guesses required to brute-force it.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A brute-force attack that executes 2&lt;sup&gt;n&lt;/sup&gt; guesses is certain to crack a password with &lt;var&gt;n&lt;/var&gt; entropy bits, and has a one-in-two chance of cracking a password with &lt;var&gt;n&lt;/var&gt;+1 entropy bits.&lt;/p&gt;
&lt;p&gt;For scale, &lt;a href=&#34;https://en.wikipedia.org/wiki/Advanced_Encryption_Standard&#34;&gt;AES-256&lt;/a&gt; encryption is currently the industry standard for strong symmetric encryption, and uses key lengths of 256-bits. An exhaustive key search over a 256-bit key space would be up against its 2&lt;sup&gt;256&lt;/sup&gt; possible permutations. When using AES-256 encryption with a key derived from a password with more than 256 entropy bits, the entropy of the AES key is the bottleneck; an attacker would fare better by doing an exhaustive key search for the AES key than a brute-force attack for the password.&lt;/p&gt;
&lt;p&gt;To calculate the entropy of a password, I recommend using a tool such as &lt;a href=&#34;https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler&#34;&gt;zxcvbn&lt;/a&gt; or &lt;a href=&#34;https://keepassxc.org/&#34;&gt;KeePassXC&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;
&lt;p&gt;Define a function &lt;var&gt;P&lt;/var&gt;. &lt;var&gt;P&lt;/var&gt; determines the probability that MOAC will correctly guess a password with &lt;var&gt;n&lt;/var&gt; bits of entropy after using &lt;var&gt;e&lt;/var&gt; energy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(n, e)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;var&gt;P&lt;/var&gt;(&lt;var&gt;n&lt;/var&gt;, &lt;var&gt;e&lt;/var&gt;) ≥ 1, the MOAC will certainly guess your password before running out of energy. The lower &lt;var&gt;P&lt;/var&gt;(&lt;var&gt;n&lt;/var&gt;, &lt;var&gt;e&lt;/var&gt;) is, the less likely it is for the MOAC to guess your password.&lt;/p&gt;
&lt;h2 id=&#34;caveats-and-estimates&#34;&gt;Caveats and estimates&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t have a strong physics background.&lt;/p&gt;
&lt;p&gt;A brute-force attack will just guess a single password until the right one is found. Brute-force attacks won&amp;rsquo;t &amp;ldquo;decrypt&amp;rdquo; stored passwords, because they&amp;rsquo;re not supposed to be stored encrypted; they&amp;rsquo;re typically &lt;a href=&#34;https://en.wikipedia.org/wiki/Salt_%28cryptography%29&#34;&gt;salted&lt;/a&gt; and hashed.&lt;/p&gt;
&lt;p&gt;When estimating, we&amp;rsquo;ll prefer higher estimates that increase the odds of it guessing a password; after all, the point of this exercise is to establish an &lt;em&gt;upper&lt;/em&gt; limit on password strength. We&amp;rsquo;ll also simplify: for instance, the MOAC will not waste any heat, and the only way it can guess a password is through brute-forcing. Focusing on too many details would defeat the point of this thought experiment.&lt;/p&gt;
&lt;p&gt;Quantum computers can use &lt;a href=&#34;https://en.wikipedia.org/wiki/Grover%27s_algorithm&#34;&gt;Grover&amp;rsquo;s algorithm&lt;/a&gt; for an exponential speed-up; to account for quantum computers using Grover&amp;rsquo;s algorithm, calculate &lt;var&gt;P&lt;/var&gt;(&lt;var&gt;n&lt;/var&gt;/2, &lt;var&gt;e&lt;/var&gt;) instead.&lt;/p&gt;
&lt;p&gt;Others are better equipped to explain encryption/hashing/key-derivation algorithms, so I won&amp;rsquo;t; this is just a pure and simple brute-force attack given precomputed password entropy, assuming that the cryptography is bulletproof.&lt;/p&gt;
&lt;p&gt;Obviously, I&amp;rsquo;m not taking into account future mathematical advances; my crystal ball broke after I asked it if humanity would ever develop the technology to make anime real.&lt;/p&gt;
&lt;p&gt;Finally, there&amp;rsquo;s always a non-zero probability of a brute-force attack guessing a password with a given entropy. Literal &amp;ldquo;immunity&amp;rdquo; is impossible. Lowering this probability to statistical insignificance renders our password practically immune to brute-force attacks.&lt;/p&gt;
&lt;h2 id=&#34;compushytation&#34;&gt;Compu­tation&lt;/h2&gt;
&lt;p&gt;How much energy does MOAC use per guess during a brute-force attack? In the context of this thought experiment, this number should be unrealistically low. I settled on &lt;a href=&#34;https://en.wikipedia.org/wiki/KT_%28energy%29&#34;&gt;&lt;var&gt;k&lt;/var&gt;&lt;var&gt;T&lt;/var&gt;&lt;/a&gt;. &lt;var&gt;k&lt;/var&gt; represents the &lt;a href=&#34;https://en.wikipedia.org/wiki/Boltzmann_constant&#34;&gt;Boltzmann Constant&lt;/a&gt; (about 1.381×10&lt;sup&gt;-23&lt;/sup&gt; J/K) and &lt;var&gt;T&lt;/var&gt; represents the temperature of the system. Their product corresponds to the amount of heat required to create a 1 nat increase in a system&amp;rsquo;s entropy.&lt;/p&gt;
&lt;p&gt;A more involved approach to picking a good value might utilize the &lt;a href=&#34;https://en.wikipedia.org/wiki/Planck%E2%80%93Einstein_relation&#34;&gt;Plank-Einstein relation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also probably a better idea to make this value an estimate for flipping a single bit, and to estimate the average number of bit-flips it takes to make a single password guess. If that bothers you, pick a number &lt;var&gt;b&lt;/var&gt; you believe to be a good estimate for a bit-flip-count and calculate &lt;var&gt;P&lt;/var&gt;(&lt;var&gt;n&lt;/var&gt;+&lt;var&gt;b&lt;/var&gt;, &lt;var&gt;e&lt;/var&gt;) instead of &lt;var&gt;P&lt;/var&gt;(&lt;var&gt;n&lt;/var&gt;, &lt;var&gt;e&lt;/var&gt;).&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s the temperature of the system? Three pieces of information help us find out:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The MOAC is located somewhere in the observable universe&lt;/li&gt;
&lt;li&gt;The MOAC will be consuming the entire observable universe&lt;/li&gt;
&lt;li&gt;The universe is mostly empty&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A good value for &lt;var&gt;T&lt;/var&gt; would be the average temperature of the entire observable universe. The universe is mostly empty; &lt;var&gt;T&lt;/var&gt; is around the temperature of cosmic background radiation in space. The lowest reasonable estimate for this temperature is 2.7 degrees Kelvin.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; A lower temperature means less energy usage, less energy usage allows more computations, and more computations raises the upper limit on password strength.&lt;/p&gt;
&lt;p&gt;Every guess, the MOAC expends &lt;var&gt;k&lt;/var&gt;&lt;var&gt;T&lt;/var&gt; energy. Let &lt;var&gt;E&lt;/var&gt; = the total amount of energy the MOAC can use; let &lt;var&gt;B&lt;/var&gt; = the maximum number of guesses the MOAC can execute before running out of energy.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;B = E/(kT)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, given the maximum number of passwords the MOAC can guess &lt;var&gt;B&lt;/var&gt; and the bits of entropy in our password &lt;var&gt;n&lt;/var&gt;, we have an equation for the probability that the MOAC will guess our password:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(n,B) = B/2ⁿ
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plug in our expression for &lt;var&gt;B&lt;/var&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;P(n,E) = E/(2ⁿkT)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;calculating-the-mass-energy-of-the-observable-universe&#34;&gt;Calculating the mass-energy of the observable universe&lt;/h3&gt;
&lt;p&gt;The MOAC can use the entire mass-energy of the observable universe.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; Simply stuff the observable universe into the attached 100% efficient furnace, turn on the burner, and generate power for the computer. You might need to ask a friend for help.&lt;/p&gt;
&lt;p&gt;Just how much energy is that? The mass-energy equivalence formula is quite simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;E = mc²
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;re trying to find &lt;var&gt;E&lt;/var&gt; and we know &lt;var&gt;c&lt;/var&gt;, the speed of light, is 299,792,458 m/s. That leaves &lt;var&gt;m&lt;/var&gt;. What&amp;rsquo;s the mass of the observable universe?&lt;/p&gt;
&lt;h3 id=&#34;calculating-the-critical-density-of-the-observable-universe&#34;&gt;Calculating the critical density of the observable universe&lt;/h3&gt;
&lt;p&gt;Critical density is smallest average density of matter required to &lt;em&gt;almost&lt;/em&gt; slow the expansion of the universe to a stop. Any more dense, and expansion will stop; any less, and expansion will never stop.&lt;/p&gt;
&lt;p&gt;Let &lt;var&gt;D&lt;/var&gt; = critical density of the observable universe and &lt;var&gt;V&lt;/var&gt; = volume of the observable universe. Mass is the product of density and volume:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m = DV
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can derive the value of D by solving for it in the &lt;a href=&#34;https://en.wikipedia.org/wiki/Friedmann_equations&#34;&gt;Friedman equations&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;D = 3Hₒ²/(8πG)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where &lt;var&gt;G&lt;/var&gt; is the &lt;a href=&#34;https://en.wikipedia.org/wiki/Gravitational_constant&#34;&gt;Gravitational Constant&lt;/a&gt; and &lt;var&gt;Hₒ&lt;/var&gt; is the &lt;a href=&#34;https://en.wikipedia.org/wiki/Hubble%27s_law&#34;&gt;Hubble Constant&lt;/a&gt;. &lt;var&gt;Hₒ&lt;/var&gt;&lt;var&gt;d&lt;/var&gt; is the rate of expansion at proper distance &lt;var&gt;d&lt;/var&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s assume the observable universe is a sphere, expanding at the speed of light ever since the Big Bang.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; The volume &lt;var&gt;V&lt;/var&gt; of our spherical universe when given its radius &lt;var&gt;r&lt;/var&gt; is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;V = (4/3)πr³
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To find the radius of the observable universe &lt;var&gt;r&lt;/var&gt;, we can use the age of the universe &lt;var&gt;t&lt;/var&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;r = ct
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hubble&amp;rsquo;s Law estimates the age of the universe to be around 1/&lt;var&gt;H&lt;/var&gt;ₒ&lt;/p&gt;
&lt;h3 id=&#34;solving-for-e&#34;&gt;Solving for E&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s plug in all the derived values into our original equation for the mass of the observable universe &lt;var&gt;m&lt;/var&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m = DV
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember when I opened the article by saying that none of the equations would be long or complex?&lt;/p&gt;
&lt;p&gt;I lied.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;m = (3Hₒ²/(8πG))(4/3)π(ct)³
m = c³/(2GHₒ)

E = mc²
E = c⁵/(2GHₒ)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yay, we found an expression for the total energy the MOAC can consume!&lt;/p&gt;
&lt;h2 id=&#34;final-solution&#34;&gt;Final Solution&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;P(n,E) = E/(2ⁿkT)
P(n, c⁵/(2GHₒ)) = c⁵/(2GHₒ*2ⁿkT)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s copy and paste the values for those constants from Wikipedia and Wolfram Alpha:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;c = 299,792,458 m/s&lt;/li&gt;
&lt;li&gt;G ≈ 6.67408×10&lt;sup&gt;-11&lt;/sup&gt; m³/kg/s²&lt;/li&gt;
&lt;li&gt;Hₒ ≈ 2.2×10&lt;sup&gt;-18&lt;/sup&gt; Hz (uncertain; look up the Hubble tension)&lt;/li&gt;
&lt;li&gt;T ≈ 2.7 K&lt;/li&gt;
&lt;li&gt;k ≈ 1.38065×10&lt;sup&gt;-23&lt;/sup&gt; J/K&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plugging those in and simplifying:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P(n) ≈ 2.21×10&lt;sup&gt;92&lt;/sup&gt; / 2&lt;sup&gt;n&lt;/sup&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here are some sample outputs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;P(256) ≈ 1.9×10&lt;sup&gt;15&lt;/sup&gt; (password certainly cracked after burning 1.9 quadrillionth of the mass-energy of the observable universe).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P(306.76) ≈ 1 (password certainly cracked after burning the mass-energy of the observable universe)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P(310) ≈ 0.11 (about one in ten)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;P(326.6) ≈ 1.1×10&lt;sup&gt;-6&lt;/sup&gt; (about one in a million)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your threat model is a bit smaller, simulate putting a smaller object into the MOAC&amp;rsquo;s furnace. For example, the Earth has a mass of 5.972×10²⁴ kg; this gives the MOAC a one-in-ten-trillion chance of cracking a password with 256 entropy bits and a 100% chance of cracking a 213-bit password.&lt;/p&gt;
&lt;h2 id=&#34;sample-unbreakable-passwords&#34;&gt;Sample unbreakable passwords&lt;/h2&gt;
&lt;p&gt;According to KeePassXC&amp;rsquo;s password generator, each of the following passwords has an entropy between 330 and 340 bits.&lt;/p&gt;
&lt;p&gt;Using the extended-ASCII character set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;¦=¦FVõ)Çb^ÄwÎ¡=,°m°B9®;&amp;gt;3[°r:t®Ú&amp;quot;$3CG¨/Bq-y\;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the characters on a standard US QWERTY layout:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%nUzL2XR&amp;amp;Tz5hJfp2tiYBoBBX^vWo3`g6H#JSC#N6gWm#hVdD~ziD$YHW
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using only alphanumeric characters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tp8D69CGWE5t5a9si5XNsw32CKyCafh8qGrKWLwE6KJHpGyUtcJDWpgRz5mFNx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An excerpt from a religious text with a trailing space:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;I&#39;d just like to interject for a moment. What you’re referring to as Linux, is in fact, GNU/Linux, 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don&amp;rsquo;t use actual excerpts from pre-existing works as your password.&lt;/p&gt;
&lt;h2 id=&#34;conclusion-tldr&#34;&gt;Conclusion, TLDR&lt;/h2&gt;
&lt;p&gt;Question: How much entropy should a password have to ensure it will &lt;em&gt;never&lt;/em&gt; be vulnerable to a brute-force attack? Can an impossibly efficient computer&amp;mdash;the MOAC&amp;mdash;crack your password?&lt;/p&gt;
&lt;p&gt;Answer: limited only by energy, if a computer with the highest level of efficiency physically possible is made of matter, does work to compute, and obeys the conservation of energy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A password with 256 bits of entropy is practically immune to brute-force attacks large enough to quite literally burn the world, but is quite trivial to crack with a universe-scale fuel source.&lt;/li&gt;
&lt;li&gt;A password with 327 bits of entropy is nearly impossible to crack even if you burn the whole observable universe trying to do so.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At that point, a formidable threat would rather use &lt;a href=&#34;https://xkcd.com/538/&#34;&gt;other means&lt;/a&gt; to unlock your secrets.&lt;/p&gt;
&lt;h2 id=&#34;further-reading-alternative-approaches&#34;&gt;Further reading: alternative approaches&lt;/h2&gt;
&lt;p&gt;Check out Scott Aaronson&amp;rsquo;s article, &lt;a href=&#34;https://www.scottaaronson.com/democritus/lec20.html&#34;&gt;Cosmology and Complexity&lt;/a&gt;. He uses an alternative approach to finding the maximum bits we can work with: he simply inverts the &lt;a href=&#34;https://en.wikipedia.org/wiki/Cosmological_constant&#34;&gt;cosmological constant&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This model takes into account more than just the mass of the observable universe. While we previously found that the MOAC can brute-force a password with 306.76 entropy bits, this model allows the same for up to 405.3 bits.&lt;/p&gt;
&lt;h3 id=&#34;approaches-that-account-for-computation-speed&#34;&gt;Approaches that account for computation speed&lt;/h3&gt;
&lt;p&gt;This article&amp;rsquo;s approach deliberately disregards computation speed, focusing only on energy required to finish a set of computations. Other approaches account for physical limits on computation speed.&lt;/p&gt;
&lt;p&gt;One well-known approach to calculating physical limits of computation is &lt;a href=&#34;https://en.wikipedia.org/wiki/Bremermann%27s_limit&#34;&gt;Bremermann&amp;rsquo;s limit&lt;/a&gt;, which calculates the speed of computation given a finite amount of mass. This article&amp;rsquo;s approach disregards time, focusing only on mass-energy equivalence.&lt;/p&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://arxiv.org/abs/quant-ph/9908043&#34;&gt;Ultimate physical limits to computation&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://meche.mit.edu/people/faculty/SLLOYD@MIT.EDU&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Seth&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Lloyd&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; further explores limits to computation speed on an ideal 1-kilogram computer.&lt;/p&gt;
&lt;h2 id=&#34;acknowledgements&#34;&gt;Ac­knowledge­ments&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://bzsombor.web.elte.hu/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Barna&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Zsombor&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span
	
	class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://rcolyer.net/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Ryan&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Coyler&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; for helping me over IRC with my shaky physics and pointing out the caveats of my approach. u/RisenSteam on Reddit also corrected an incorrect reference to AES-256 encryption by bringing up salts.&lt;/p&gt;
&lt;p&gt;My notes from Thermal Physics weren&amp;rsquo;t enough to write this; various Wikipedia articles were also quite helpful, most of which were linked in the body of the article.&lt;/p&gt;
&lt;p&gt;While I was struggling to come up with a good expression for the minimum energy used per password guess, I stumbled upon &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.schneier.com/books/applied-cryptography/&#34;&gt;Applied Cryptography&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://schneier.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Bruce&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Schneier&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;. An excerpt &lt;a href=&#34;https://www.schneier.com/blog/archives/2009/09/the_doghouse_cr.html&#34;&gt;on his blog&lt;/a&gt; involving setting the minimum energy per computation to &lt;var&gt;k&lt;/var&gt;&lt;var&gt;T&lt;/var&gt;. I chose a more conservative estimate for &lt;var&gt;T&lt;/var&gt; than Schneier did, and a &lt;em&gt;much&lt;/em&gt; greater source of energy.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;span&gt;James Massey (1994). &amp;ldquo;Guessing and entropy&amp;rdquo; (PDF). Proceedings of 1994 IEEE International Symposium on Information Theory. IEEE. p. 204.&lt;/span&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;span&gt;Assis, A. K. T.; Neves, M. C. D. (3 July 1995). &amp;ldquo;History of the 2.7 K Temperature Prior to Penzias and Wilson&amp;rdquo;&lt;/span&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;The MOAC 2 was supposed to be able to consume other sources of energy such as dark matter and dark energy. Unfortunately, Intergalactic Business Machines ran out of funds since all their previous funds, being made of matter, were consumed by the original MOAC.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;This is a massive oversimplification; there isn&amp;rsquo;t a single answer to the question &amp;ldquo;What is the volume of the observable universe?&amp;rdquo; Using this speed-of-light approach is one of multiple valid perspectives. The absolute size of the observable universe is much greater due to the way expansion works, but stuffing that into the MOAC&amp;rsquo;s furnace would require moving mass faster than the speed of light.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Best practices for inclusive textual websites</title>
      <link>https://envs.net/~seirdy/posts/2020/11/23/website-best-practices/</link>
      <pubDate>Mon, 23 Nov 2020 20:21:35 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2020/11/23/website-best-practices/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2020/11/23/website-best-practices/">&lt;section role=&#34;doc-preface&#34;&gt;
&lt;h2 id=&#34;before-you-begin&#34;&gt;Before you begin&lt;/h2&gt;
&lt;p&gt;The following applies to minimal websites that focus primarily on text. It does not apply to websites that have a lot of non-textual content. It also does not apply to websites that focus more on generating revenue or pleasing investors than being inclusive.&lt;/p&gt;
&lt;p&gt;This is a &amp;ldquo;living document&amp;rdquo; that I add to as I receive feedback. See the updated date and changelog after the post title.&lt;/p&gt;
&lt;p role=&#34;doc-tip&#34;&gt;If you find the article too long, just read the introduction and conclusion. The table of contents should help you skim.&lt;/p&gt;
&lt;/section&gt;
&lt;details id=&#34;toc&#34;&gt;
&lt;summary&gt;Toggle table of contents&lt;/summary&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;&lt;nav id=&#34;TableOfContents&#34;&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href=&#34;#introduction&#34;&gt;Intro­duction&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#inclusive-design&#34;&gt;Inclusive design&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#restricted-enhancement&#34;&gt;Restricted enhancement&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#prior-art&#34;&gt;Prior art&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#why-this-article-exists&#34;&gt;Why this article exists&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#security-and-privacy&#34;&gt;Security and privacy&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#tls&#34;&gt;TLS&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#scripts-and-the-content-security-policy&#34;&gt;Scripts and the Content Security Policy&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#if-you-must-enable-scripts&#34;&gt;If you must enable scripts&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#third-party-content&#34;&gt;Third-party content&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#optimal-loading&#34;&gt;Optimal loading&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#blocking-resources&#34;&gt;Blocking resources&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#dont-count-on-the-cache&#34;&gt;Don&amp;rsquo;t count on the cache&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#inline-content&#34;&gt;Inline content&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#transfer-size-and-user-flows&#34;&gt;Transfer size and user flows&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#core-web-vitals-arent-enough&#34;&gt;Core Web Vitals aren&amp;rsquo;t enough&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#round-trips&#34;&gt;Round trips&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#the-golden-kilobyte&#34;&gt;The golden kilobyte&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#layout-shifts&#34;&gt;Layout shifts&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#other-server-side-tweaks&#34;&gt;Other server-side tweaks&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#against-lazy-loading&#34;&gt;Against lazy loading&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#against-speculative-pre-loading&#34;&gt;Against speculative pre-loading&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#cant-users-on-poor-connections-disable-images&#34;&gt;Can&amp;rsquo;t users on poor connections disable images?&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#related-issues&#34;&gt;Related issues&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#long-page-performance&#34;&gt;Long-page performance&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#css-containment&#34;&gt;CSS containment&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#performance-of-assistive-technologies&#34;&gt;Performance of assistive technologies&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#old-browsers&#34;&gt;Old browsers&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#old-browsers-in-use&#34;&gt;Old browsers in use&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#how-to-support-old-browsers&#34;&gt;How to support old browsers&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#the-tor-browser&#34;&gt;The Tor Browser&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#constraints-of-the-tor-browser&#34;&gt;Constraints of the Tor Browser&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#hidden-services&#34;&gt;Hidden services&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#in-page-search&#34;&gt;In-page search&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#the-importance-of-proofreading&#34;&gt;The importance of proofreading&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#problematic-overrides&#34;&gt;Problematic overrides&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#about-fonts&#34;&gt;About fonts&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#but-most-users-dont-change-their-fonts&#34;&gt;But most users don&amp;rsquo;t change their fonts&amp;hellip;&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#stylesheet-overrides-arent-an-excuse&#34;&gt;Style­sheet overrides aren&amp;rsquo;t an excuse&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#font-fingerprinting-concerns&#34;&gt;Font fingerprinting concerns&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#zoom-and-font-size&#34;&gt;Zoom and font size&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#beyond-alt-text&#34;&gt;Beyond alt-text&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#putting-images-in-context&#34;&gt;Putting images in context&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#figures&#34;&gt;Figures&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#image-transcripts&#34;&gt;Image transcripts&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#about-custom-colors&#34;&gt;About custom colors&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#default-colors&#34;&gt;Default colors&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#color-overrides-and-accessibility&#34;&gt;Color overrides and accessibility&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#dark-themes&#34;&gt;Dark themes&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#use-the-advanced-perceptual-contrast-algorithm&#34;&gt;Use the Advanced Perceptual Contrast Algorithm&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#what-contrast-algorithms-dont-cover-over-saturation&#34;&gt;What contrast algorithms don&amp;rsquo;t cover: over-saturation&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#contrast-under-different-conditions&#34;&gt;Contrast under different conditions&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#visible-interactive-semantics&#34;&gt;Visible interactive semantics&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#in-defense-of-link-underlines&#34;&gt;In defense of link underlines&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#buttons-versus-links&#34;&gt;Buttons versus links&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#visible-non-interactive-semantics&#34;&gt;Visible non-interactive semantics&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#against-focusable-containers&#34;&gt;Against focusable containers&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#image-optimization&#34;&gt;Image optimization&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#breaking-conventional-wisdom&#34;&gt;Breaking conventional wisdom&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#enforce-image-compression&#34;&gt;Enforce image compression&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#dark-image-variants&#34;&gt;Dark image variants&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#svg-images&#34;&gt;SVG images&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#layout&#34;&gt;Layout&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#accessible-skimming&#34;&gt;Accessible skimming&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#friendly-navigation&#34;&gt;Friendly navigation&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#single-column-layout&#34;&gt;Single-column layout&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#sidebar-pitfalls&#34;&gt;Sidebar pitfalls&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#sidebar-alternatives&#34;&gt;Sidebar alternatives&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#line-length&#34;&gt;Line length&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#small-viewports&#34;&gt;Small viewports&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#narrow-viewports-are-popular&#34;&gt;Narrow viewports are popular&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#wide-items&#34;&gt;Wide items&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#keeping-text-together&#34;&gt;Keeping text together&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#pictures-of-text&#34;&gt;Pictures of text&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#indented-elements&#34;&gt;Indented elements&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#short-viewports&#34;&gt;Short viewports&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#spacing&#34;&gt;Spacing&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#non-interactive-space&#34;&gt;Non-interactive space&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#tap-targets&#34;&gt;Tap targets&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#line-spacing&#34;&gt;Line spacing&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#non-browsers-reading-mode&#34;&gt;Non-&lt;wbr /&gt;browsers: reading mode&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#machine-translation&#34;&gt;Machine translation&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#posh-helps-translation-engines&#34;&gt;POSH helps translation engines&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#changing-text-direction&#34;&gt;Changing text direction&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#current-limitations&#34;&gt;Current limitations&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#inaccessible-default-stylesheets&#34;&gt;In­accessible default stylesheets&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#monospace-handling&#34;&gt;Mono­space handling&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#focus-indicators&#34;&gt;Focus indicators&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#screen-reader-improvements&#34;&gt;Screen reader improve­ments&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#split-elements-and-possessive-hyperlinks&#34;&gt;Split elements and possessive hyperlinks&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#other-tips-for-screen-readers&#34;&gt;Other tips for screen readers&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#future-users&#34;&gt;Future users&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#third-parties&#34;&gt;Third parties&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#dead-links&#34;&gt;Dead links&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#reproducibility&#34;&gt;Reproducibility&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#testing&#34;&gt;Testing&lt;/a&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&#34;#automated-tests&#34;&gt;Automated tests&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&#34;#unorthodox-tests&#34;&gt;Unorthodox tests&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#future-updates&#34;&gt;Future updates&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#conclusion&#34;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&#34;#further-reading&#34;&gt;Ack­nowledge­ments and further reading&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p&gt;I realize not everybody&amp;rsquo;s going to ditch the Web and switch to Gemini or Gopher today (&lt;span data-literal=&#34;that would be a difficult and unrealistic transition&#34;&gt;that&amp;rsquo;ll take, like, at least a month /s&lt;/span&gt;). Until that happens, here&amp;rsquo;s a non-exhaustive, highly-opinionated list of best practices for websites that focus primarily on text. I don&amp;rsquo;t expect anybody to fully agree with the list; nonetheless, the article should have at least some useful information for any web content author or front-end web developer.&lt;/p&gt;
&lt;h3 id=&#34;inclusive-design&#34;&gt;Inclusive design&lt;/h3&gt;
&lt;p&gt;My primary focus is &lt;a href=&#34;https://100daysofa11y.com/2019/12/03/accommodation-versus-inclusive-design/&#34;&gt;inclusive design&lt;/a&gt;. Specifically, I focus on supporting &lt;em&gt;underrepresented ways to read a page&lt;/em&gt;. Not all users load a page in a common web-browser and navigate effortlessly with their eyes and hands. Authors often neglect people who read through accessibility tools, tiny viewports, machine translators, &amp;ldquo;reading mode&amp;rdquo; implementations, the Tor network, printouts, hostile networks, and uncommon browsers, to name a few. I list more niches in &lt;a href=&#34;#conclusion&#34;&gt;the conclusion&lt;/a&gt;. Compatibility with so many niches sounds far more daunting than it really is: if you only selectively override browser defaults and use plain-old, semantic HTML (&lt;abbr title=&#34;plain-old, semantic HTML&#34;&gt;POSH&lt;/abbr&gt;), you&amp;rsquo;ve done half of the work already.&lt;/p&gt;
&lt;p&gt;One of the core ideas behind the flavor of inclusive design I present is &lt;dfn id=&#34;inc-by-default&#34; tabindex=&#34;-1&#34;&gt;inclusivity by default&lt;/dfn&gt;. Web pages shouldn&amp;rsquo;t use accessible overlays, reduced-data modes, or other personalizations if these features can be available all the time. Personalization isn&amp;rsquo;t always possible: Tor users, students using school computers, and people with restrictive corporate policies can&amp;rsquo;t &amp;ldquo;make websites work for them&amp;rdquo;; that&amp;rsquo;s a webmaster&amp;rsquo;s responsibility.&lt;/p&gt;
&lt;p&gt;At the same time, many users do apply personalizations; sites should respect those personalizations whenever possible. Balancing these two needs is difficult. Some features conflict; you can&amp;rsquo;t display a light and dark color scheme simultaneously. Personalization is a fallback strategy to resolve conflicting needs. Dis­proportionately underrepresented needs deserve disproportionately greater attention, so they come before personal preferences instead of being relegated to a separate lane.&lt;/p&gt;
&lt;h3 id=&#34;restricted-enhancement&#34;&gt;Restricted enhancement&lt;/h3&gt;
&lt;p&gt;Another focus is minimalism. &lt;a href=&#34;https://en.wikipedia.org/wiki/Progressive_enhancement&#34;&gt;Progressive enhancement&lt;/a&gt; is a simple, safe idea that tries to incorporate some responsibility into the design process without rocking the boat too much. I don&amp;rsquo;t find it radical enough. I call my alternative approach &amp;ldquo;restricted enhancement&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;dfn&gt;Restricted enhancement&lt;/dfn&gt; limits all enhancements to those that solve specific accessibility, security, performance, or significant usability problems faced by people besides the author. These enhancements must be made progressively when possible, with a preference for using older or more widespread features, taking into account unorthodox user agents. Purely-cosmetic changes should be kept to a minimum.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d like to re-iterate yet another time that this only applies to websites that primarily focus on text. If graphics, interactivity, etc. are an important part of your website, less of the article applies. My hope is for readers to consider a subset of this page the next time they build a website, and &lt;em&gt;address the trade-offs they make when they deviate.&lt;/em&gt; I don&amp;rsquo;t expect&amp;mdash;or want&amp;mdash;anybody to follow all of my advice, because doing so would make the Web quite a boring place!&lt;/p&gt;
&lt;p&gt;Our goal: make a textual website maximally inclusive, using restricted enhancement.&lt;/p&gt;
&lt;h3 id=&#34;prior-art&#34;&gt;Prior art&lt;/h3&gt;
&lt;p&gt;You can regard this article as an elaboration on existing work by the Web Accessibility Initiative (&lt;abbr title=&#34;Web Accessibility Initiative’s&#34;&gt;WAI&lt;/abbr&gt;).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll cite the &lt;abbr&gt;WAI&amp;rsquo;s&lt;/abbr&gt; &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/&#34;&gt;Techniques for WCAG 2.2&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; a number of times. Each &amp;ldquo;Success Criterion&amp;rdquo; (requirement) of the WCAG has possible techniques. Unlike the &lt;cite&gt;Web Content Accessibility Guidelines&lt;/cite&gt; (&lt;abbr title=&#34;Web Content Accessibility Guidelines&#34;&gt;WCAG&lt;/abbr&gt;), the Techniques document does not list requirements; rather, it serves to non-exhaustively educate authors about &lt;em&gt;how&lt;/em&gt; to use specific technologies to comply with the WCAG. I don&amp;rsquo;t find much utility in the technology-agnostic goals enumerated by the WCAG without the accompanying technology-specific techniques to meet those goals.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll also cite &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/TR/coga-usable/&#34;&gt;Making Content Usable for People with Cognitive and Learning Disabilities&lt;/a&gt;&lt;/cite&gt;, by &lt;span&gt;&lt;span&gt;the WAI&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. The document lists eight objectives. Each objective has associated personas, and can be met by several design patterns.&lt;/p&gt;
&lt;h3 id=&#34;why-this-article-exists&#34;&gt;Why this article exists&lt;/h3&gt;
&lt;p&gt;Performance and accessibility guidelines are scattered across multiple WAI documents and blog posts. Moreover, guidelines tend to be overly general and avoid giving specific advice. Guidelines from different places tend to contradict each other, especially when they have different goals (e.g., security and accessibility). They also tend to be focused on large corporate sites rather than the simple text-oriented content the Web was made for.&lt;/p&gt;
&lt;p&gt;I wanted to create a single reference with non-contradictory guidelines, containing advice more specific and opinionated than existing material. I also wanted to approach the very different aspects of site design from the same perspective and in the same place, allowing readers to draw connections between them.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;security-and-privacy&#34;&gt;Security and privacy&lt;/h2&gt;
&lt;p&gt;One of the defining differences between textual websites and advanced Web 2.0 sites/apps is safety. Most browser vulnerabilities are related to modern Web features like JavaScript and WebGL. The simplicity of basic textual websites should guarantee some extra safety; however, webmasters need to take additional measures to ensure limited use of &amp;ldquo;modern&amp;rdquo; risky features.&lt;/p&gt;
&lt;h3 id=&#34;tls&#34;&gt;TLS&lt;/h3&gt;
&lt;p&gt;Hostile networks are the norm, and &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/notes/2022/08/03/on-enforcing-https/&#34;&gt;your site is an attack vector&lt;/a&gt;. All of the simplicity in the world won&amp;rsquo;t protect a page from unsafe content injection by an intermediary. Proper use of TLS protects against page alteration in transit and ensures a limited degree of privacy. Test your TLS setup with &lt;a translate=&#34;no&#34; href=&#34;https://testssl.sh/&#34;&gt;testssl.sh&lt;/a&gt; and &lt;a href=&#34;https://webbkoll.dataskydd.net/&#34;&gt;Webbkoll&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If your OpenSSL (or equivalent) version is outdated or you don&amp;rsquo;t want to download and run a shell script, SSL Labs&amp;rsquo; &lt;a href=&#34;https://www.ssllabs.com/ssltest/&#34;&gt;SSL Server Test&lt;/a&gt; should be equivalent to testssl.sh. Mozilla&amp;rsquo;s &lt;a href=&#34;https://observatory.mozilla.org/&#34;&gt;HTTP Observatory&lt;/a&gt; offers a subset of Webbkoll&amp;rsquo;s features and is a bit out of date (and requires JavaScript), but it also gives a beginner-friendly score. Most sites should strive for at least a 50, but a score of 100 or even 120 shouldn&amp;rsquo;t be too hard to reach.&lt;/p&gt;
&lt;p&gt;A false sense of security is far worse than transparent insecurity. Don&amp;rsquo;t offer broken TLS ciphers, including TLS 1.0 and 1.1. Vintage computers can run TLS 1.2 implementations such as BearSSL surprisingly efficiently, leverage a TLS terminator, or they can use a plain unencrypted connection. &lt;a href=&#34;https://oldvcr.blogspot.com/2022/07/crypto-ancienne-20-now-brings-tls-13-to.html&#34;&gt;Ancienne 2.0 brings TLS 1.3 to 90s-era machines&lt;/a&gt;. A broken cipher suite is security theater.&lt;/p&gt;
&lt;h3 id=&#34;scripts-and-the-content-security-policy&#34;&gt;Scripts and the Content Security Policy&lt;/h3&gt;
&lt;p&gt;Consider taking hardening measures to maximize the security benefits made possible by the simplicity of textual websites, starting with script removal.&lt;/p&gt;
&lt;p&gt;JavaScript and WebAssembly are responsible for the bulk of modern web exploits. If that isn&amp;rsquo;t reason enough, most &lt;a href=&#34;https://envs.net/~seirdy/2021/03/10/search-engines-with-own-indexes/&#34;&gt;non-mainstream search indexes&lt;/a&gt; have little to no support for JavaScript. Ideally, a text-oriented site can enforce a scripting ban at the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP&#34;&gt;Content Security Policy&lt;/a&gt; (&lt;abbr title=&#34;Content Security Policy&#34;&gt;CSP&lt;/abbr&gt;) level.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-12-caption&#34;&gt;
	&lt;span id=&#34;code-12&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 12&lt;/strong&gt;&lt;/span&gt;:
this is the CSP for my main website, with hashes removed for readability.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;default-src &#39;none&#39;;
img-src &#39;self&#39;;
media-src &#39;self&#39;;
style-src &#39;sha256-HASH&#39;;
frame-ancestors &#39;none&#39;;
base-uri &#39;none&#39;;
form-action FORM_DESTS;
manifest-src &#39;self&#39;;
upgrade-insecure-requests;
sandbox allow-same-origin allow-forms
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;p&gt;&lt;code&gt;default-src: &#39;none&#39;&lt;/code&gt; implies &lt;code&gt;script-src: &#39;none&#39;&lt;/code&gt;, causing a compliant browser to forbid the loading of scripts. Furthermore, the &lt;code&gt;sandbox&lt;/code&gt; CSP directive forbids a &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox&#34;&gt;wide variety of risky actions&lt;/a&gt;. While &lt;code&gt;script-src&lt;/code&gt; restricts script loading, &lt;code&gt;sandbox&lt;/code&gt; can also restrict script execution with stronger defenses against script injection (e.g. by a browser add-on).&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; I added the &lt;code&gt;allow-same-origin&lt;/code&gt; parameter so that signed scripts (e.g. from add-ons) will still be able to function.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re able to control your HTTP headers, then use headers instead of a &lt;code&gt;&amp;lt;meta http=equiv&amp;gt;&lt;/code&gt; tag. In addition to not supporting certain directives, a CSP in a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag might let some items slip through.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
	&lt;p&gt;
	At the time of inserting the &lt;code&gt;meta&lt;/code&gt; element to the document, it is
	possible that some resources have already been fetched. For example, images might be stored in
	the &lt;a href=&#34;https://html.spec.whatwg.org/multipage/images.html#list-of-available-images&#34;&gt;list of available images&lt;/a&gt; prior to dynamically inserting a &lt;code&gt;meta&lt;/code&gt;
	element with an &lt;code&gt;http-equiv&lt;/code&gt; attribute in the Content security policy state.
	Resources that have already been fetched are not guaranteed to be blocked by a Content
	Security Policy that’s enforced late.
	&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;HTML Living Standard&lt;/cite&gt;, section 4.2.5.3: Pragma directives,
&lt;a class=&#34;u-url&#34; href=&#34;https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-security-policy&#34;&gt;Content Security Policy state&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&#34;if-you-must-enable-scripts&#34;&gt;If you must enable scripts&lt;/h3&gt;
&lt;p&gt;Please use progressive enhancement (&lt;abbr title=&#34;progressive enhancement&#34;&gt;PE&lt;/abbr&gt;)&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; throughout your site; every feature possible should be optional, and scripting is no exception.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m sure you&amp;rsquo;re a great person, but your readers might not know that; don&amp;rsquo;t expect them to trust your website. Your scripts should look as safe as possible to an untrusting eye. Avoid requesting permissions or using &lt;a href=&#34;https://browserleaks.com/javascript&#34;&gt;sensitive APIs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, consider using your CSP to restrict script loading. If you must use inline scripts, selectively allow them with a hash or nonce. &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types&#34;&gt;Some recent CSP directives&lt;/a&gt; restrict and enforce proper use of &lt;a href=&#34;https://web.dev/trusted-types/&#34;&gt;trusted types&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;third-party-content&#34;&gt;Third-party content&lt;/h3&gt;
&lt;p&gt;Third-party content will complicate the CSP, allow more actors to track users, possibly slow page loading, and create more points of failure. Some privacy-conscious users actually block third-party content: while doing so is fingerprintable, it can &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/posts/2022/06/25/two-types-of-privacy/&#34;&gt;reduce the amount of data collected about an already-identified user&lt;/a&gt;. Avoid third-party content, if at all possible.&lt;/p&gt;
&lt;p&gt;Some web developers deliver resources using a third-party content delivery network (&lt;abbr title=&#34;content delivery network&#34;&gt;CDN&lt;/abbr&gt;), such as jsDelivr or Unpkg. Traditional wisdom held that doing so would allow different websites to re-use cached resources; however, &lt;a href=&#34;https://privacycg.github.io/storage-partitioning/&#34;&gt;mainstream browsers partition their caches&lt;/a&gt; to prevent this behavior.&lt;/p&gt;
&lt;p&gt;If you must use third-party content, use &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity&#34;&gt;subresource integrity&lt;/a&gt; (check the &lt;a href=&#34;https://www.w3.org/TR/SRI/&#34;&gt;&lt;abbr title=&#34;Subresource Integrity&#34;&gt;SRI&lt;/abbr&gt; specification&lt;/a&gt;). This prevents alteration without your consent. If you wish to be extra careful, you could use SRI for first-party resources too.&lt;/p&gt;
&lt;p&gt;Be sure to check the privacy policies for the third party services and subscribe to updates, as their practices could impact the privacy of all your users.&lt;/p&gt;
&lt;p&gt;For embedded third-party content (e.g. images), give extra consideration to the &lt;a href=&#34;#beyond-alt-text&#34;&gt;&amp;ldquo;Beyond alt-text&amp;rdquo; section&lt;/a&gt;. Your page should be as useful as possible if the embedded content becomes inaccessible.&lt;/p&gt;
&lt;h2 id=&#34;optimal-loading&#34;&gt;Optimal loading&lt;/h2&gt;
&lt;p&gt;Nearly every Internet user has to deal with unreliable connections every now and then, even the most privileged. Developing regions lack modern Internet infrastructure; high-ranking executives travel frequently. Everybody hits the worst end of the bell-curve.&lt;/p&gt;
&lt;p&gt;Reducing load time is especially useful to poorly-connected users. For much of the world, connectivity comes in short bursts during which loading time is precious. Chances of a connection failure or packet loss increase with time.&lt;/p&gt;
&lt;p&gt;Optimal loading is a complex topic. Broadly, it covers three overlapping categories: reducing payload size, delivering content early, and reducing the number of requests and round trips.&lt;/p&gt;
&lt;h3 id=&#34;blocking-resources&#34;&gt;Blocking resources&lt;/h3&gt;
&lt;p&gt;HTML is a blocking resource: images and stylesheets will not load until the user agent loads and parses the HTML that calls them. To start loading above-the-fold images before the HTML parsing finishes, send a &lt;code&gt;link&lt;/code&gt; HTTP header.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-13-caption&#34;&gt;
	&lt;span id=&#34;code-13&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 13&lt;/strong&gt;&lt;/span&gt;:
my website includes a &lt;code&gt;link&lt;/code&gt; header to load the image that serves as my IndieWeb photo and favicon. The header includes a &lt;a href=&#34;https://wicg.github.io/priority-hints/&#34;&gt;priority hint&lt;/a&gt; so the browser starts downloading the resource right away.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;link: &amp;lt;/favicon.HASH.svg&amp;gt;; rel=preload; as=image; fetchpriority=high
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;dont-count-on-the-cache&#34;&gt;Don&amp;rsquo;t count on the cache&lt;/h3&gt;
&lt;p&gt;The browser cache is a valuable tool to save bandwidth and improve page speed, but it&amp;rsquo;s not as reliable as many people seem to believe. Don&amp;rsquo;t focus too much on &amp;ldquo;repeat view&amp;rdquo; performance.&lt;/p&gt;
&lt;p&gt;Out of privacy concerns, most browsers no longer re-use cached content across sites; refer back to the &lt;a href=&#34;#third-party-content&#34;&gt;section on third-party content&lt;/a&gt; for more details. Privacy-conscious users (including all users using &amp;ldquo;private&amp;rdquo; or &amp;ldquo;incognito&amp;rdquo; sessions) will likely have their caches wiped between sessions.&lt;/p&gt;
&lt;p&gt;Requesting a high number of cached resources can decrease performance of the cache, causing browsers to &lt;a href=&#34;https://simonhearne.com/2020/network-faster-than-cache/&#34;&gt;bypass the cache&lt;/a&gt;. The effect is especially pronounced on low-end phones and mechanical hard drives. Firefox calls this feature &amp;ldquo;Race Cache With Network&amp;rdquo;, documented in &lt;a href=&#34;https://bugzilla.mozilla.org/show_bug.cgi?id=1358038&#34;&gt;Mozilla Bug 1358038&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One way to help browsers decide which disk-cached resources to prioritize is to use immutable assets. Include the &lt;code&gt;immutable&lt;/code&gt; directive in your &lt;code&gt;cache-control&lt;/code&gt; headers, and cache-bust modified assets by changing their URLs. You can also keep your asset counts low by combining textual assets (e.g. CSS) and inlining small resources.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-14-caption&#34;&gt;
	&lt;span id=&#34;code-14&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 14&lt;/strong&gt;&lt;/span&gt;:
I mark my website&amp;rsquo;s assets as &amp;ldquo;immutable&amp;rdquo; and cache-bust them by including checksums in their filenames.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;cache-control: max-age=31557600, immutable
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;inline-content&#34;&gt;Inline content&lt;/h3&gt;
&lt;p&gt;In addition to HTML, CSS is also a blocking resource. You could pre-load your CSS using a &lt;code&gt;link&lt;/code&gt; header. Alternatively: if your compressed CSS is under a kilobyte consider inlining it in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; using a &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; element. Simply inlining stylesheets can pose a security threat, but the &lt;code&gt;style-src&lt;/code&gt; &lt;abbr title=&#34;Content Security Policy&#34;&gt;CSP&lt;/abbr&gt; directive can mitigate this if you include a hash of your inline stylesheet sans trailing whitespace.&lt;/p&gt;
&lt;p&gt;Consider inlining images under 250 bytes with a &lt;code&gt;data:&lt;/code&gt; URI; that&amp;rsquo;s the size at which cache-validation requests might outweigh the size of the image. My 32-pixel PNG site icon is under 150 bytes and inlines quite nicely. On this site&amp;rsquo;s hidden service, it&amp;rsquo;s often the only image on a page (the hidden service replaces SVGs with PNGs; see the section on &lt;a href=&#34;#the-tor-browser&#34;&gt;the Tor Browser&lt;/a&gt;). Inlining this image and the stylesheet allows my hidden service&amp;rsquo;s homepage to load in a single request, which is a welcome improvement given the round-trip latency that plagues onion routing implementations.&lt;/p&gt;
&lt;h3 id=&#34;transfer-size-and-user-flows&#34;&gt;Transfer size and user flows&lt;/h3&gt;
&lt;p&gt;I find advice on page weight to be too simplistic. I prefer the perspective of what the industry calls &amp;ldquo;user flows&amp;rdquo;.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;More than one way is available to locate a Web page within a set of Web pages except where the Web Page is the result of, or a step in, a process.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/TR/WCAG22/&#34;&gt;WCAG 2.2&lt;/a&gt;&lt;/cite&gt;,
&lt;a href=&#34;https://w3c.github.io/wcag/guidelines/22/#multiple-ways&#34;&gt;Success Criterion 2.4.5 Multiple Ways&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Here are some example flows that start with loading a homepage:&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A homepage has a link to a list of pages in a category. Your reader loads the homepage, navigates to the list page, and then navigates to the target page.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A homepage contains a link to a post which has &amp;ldquo;next post&amp;rdquo; and &amp;ldquo;previous post&amp;rdquo; links at the bottom. Your reader navigates to the post and clicks &amp;ldquo;next post&amp;rdquo; until they reach the target page.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A homepage has a &amp;ldquo;search&amp;rdquo; box. The reader searches for the target page and clicks a result on the result page.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assume one of your readers has caching enabled, but their current cache is empty. They have a link to your homepage. Your reader should be able to perform at least two different flows to reach a target page, starting with navigating to your homepage. The total size transferred across their entire flow is the metric worth optimizing, not the weight of a single page. Set a performance budget for this flow. A &amp;ldquo;home, posts list, target page&amp;rdquo; flow can take a user from my homepage to this page using under 150 KiB.&lt;/p&gt;
&lt;p&gt;Data is a scarce resource on metered connections; don&amp;rsquo;t waste it on unnecessary information. At least half the data transferred across the flow should be semantically-meaningful compressed markup. Try testing a &amp;ldquo;lite&amp;rdquo; version of a page with non-semantic markup removed: strip any &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; elements, or attributes that don&amp;rsquo;t have semantic value. Compare this &amp;ldquo;lite&amp;rdquo; page&amp;rsquo;s compressed markup size with the total download size of an actual page. Do this for every page across a flow.&lt;/p&gt;
&lt;p&gt;I personally found this to be too much work. I skipped the creation of &amp;ldquo;lite&amp;rdquo; pages by removing non-semantic markup from my HTML: with the exception of utility classes that describe content rather than structure, my markup is made of semantically-relevant POSH, ARIA, Microdata, and microformats classes.&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;core-web-vitals-arent-enough&#34;&gt;Core Web Vitals aren&amp;rsquo;t enough&lt;/h3&gt;
&lt;p&gt;Download size matters, especially on metered connections. There&amp;rsquo;s no shortage of advice concerning minimizing this easy-to-understand metric. Unfortunately, it alone doesn&amp;rsquo;t give us the full picture: download size is not the exact same thing as time taken to deliver useful content to users.&lt;/p&gt;
&lt;p&gt;Google&amp;rsquo;s answer to this problem is &amp;ldquo;Core Web Vitals&amp;rdquo; containing metrics such as &lt;a href=&#34;https://docs.webpagetest.org/metrics/speedindex/&#34;&gt;the Speed Index&lt;/a&gt;. These metrics aren&amp;rsquo;t useless, but they are incredibly naive: they only take into account user-perceivable speed with an emphasis on user engagement, placing too little emphasis a page&amp;rsquo;s actual resource use. Plenty of other factors exist.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Speed­Index is based on the idea that what counts is how fast the visible part of the website renders. It doesn&amp;rsquo;t matter what&amp;rsquo;s happening elsewhere on the page. It doesn&amp;rsquo;t matter if the network is saturated and your phone is hot to the touch. It doesn&amp;rsquo;t matter if the battery is visibly draining. Everything is OK as long as the part of the site in the viewport appears to pop into view right away.&lt;/p&gt;
&lt;p&gt;Of course, it doesn’t matter how fast the site appears to load if the first thing the completed page does is serve an interstitial ad. Or, if like many mobile users, you start scrolling immediately and catch the &amp;lsquo;unoptimized&amp;rsquo; part of the page with its pants down.&lt;/p&gt;
&lt;p&gt;There is only one honest measure of web performance: &lt;strong&gt;the time from when you click a link to when you&amp;rsquo;ve finished skipping the last ad.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Everything else is bullshit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://idlewords.com/about.htm&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Maciej&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Cegłowski&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://idlewords.com/talks/website_obesity.htm&#34;&gt;The Website Obesity Crisis&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;round-trips&#34;&gt;Round trips&lt;/h3&gt;
&lt;p role=&#34;doc-tip&#34;&gt;This sub-section is overkill for most use-cases.&lt;/p&gt;
&lt;p&gt;A supplementary metric to use alongside download size is round trips. Estimate the number of bytes and round-trips it takes to do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Begin downloading the final blocking resource&lt;/li&gt;
&lt;li&gt;Finish downloading all blocking resources&lt;/li&gt;
&lt;li&gt;Finish downloading two screenfuls of content&lt;/li&gt;
&lt;li&gt;Finish downloading the full page.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Understanding round-trips requires understanding your server&amp;rsquo;s approach to congestion control.&lt;/p&gt;
&lt;p&gt;Historically, TCP congestion control approaches typically set an initial window size to ten TCP packets and grew this value with each round-trip. Under most setups, this meant that the first round-trip could include 14.6 kilobytes. The following round-trip could deliver under thirty kilobytes.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; Try to ensure that all non-markup blocking resources and your document&amp;rsquo;s &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; fit within this 14.6 kilobyte budget.&lt;/p&gt;
&lt;p&gt;Nowadays, servers employ BBR-based congestion control. It allows for regular &amp;ldquo;spikes&amp;rdquo; in window size, but the initial window size is still small. Find more details in the slides from &lt;span class=&#34;h-cite&#34;&gt; &lt;cite class=&#34;p-name&#34; &gt;&lt;a class=&#34;u-url&#34; href=&#34;https://labs.apnic.net/presentations/store/2019-09-05-bbr.pdf&#34;&gt;TCP and BBR&lt;/a&gt;&lt;/cite&gt; (&lt;span&gt;application/&lt;wbr /&gt;pdf&lt;/span&gt;) by &lt;span
	
	class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.potaroo.net/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Geoff&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Huston&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
	from &lt;span class=&#34;p-org org&#34;&gt;
		&lt;a class=&#34;organization-name&#34; href=&#34;https://www.apnic.net/&#34;&gt;
			&lt;span&gt;APNiC&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;HTTP/3 uses QUIC instead of TCP, which makes things a bit different; the important thing to remember is that &lt;em&gt;user agents should be aware of all blocking resources &lt;strong&gt;before&lt;/strong&gt; finishing the earliest possible round-trip.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;the-golden-kilobyte&#34;&gt;The golden kilobyte&lt;/h3&gt;
&lt;p&gt;One of the benefits of HTTP/2 and HTTP/3 is multiplexing: multiple resources can download over a single connection. Try to initiate downloads for blocking resources as soon as possible.&lt;/p&gt;
&lt;p&gt;A TCP packet is 1460 bytes. Your first TCP packet will be partly taken up by a stapled TLS certificate, leaving you with under one kilobyte to work with.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; Make good use of this golden kilobyte; most or all of it will likely be taken up by HTTP headers.&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; Ideally, the first kilobyte transferred should inform the client of all blocking resources required, possibly using preload directives; all of these resources can then begin downloading over the same multiplexed HTTP/2 connection before the current round-trip finishes! Note that this works best if you took &lt;a href=&#34;#third-party-content&#34;&gt;my advice to avoid third-party content&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Apply these strategies in moderation. Including extra preload directives in your document markup might not help as much as you think, since their impact on page size could negate minor improvements. Micro-optimizations have diminishing returns; past a certain point, your effort is better spent elsewhere.&lt;/p&gt;
&lt;h3 id=&#34;layout-shifts&#34;&gt;Layout shifts&lt;/h3&gt;
&lt;p&gt;Loading content of unknown dimensions, such as images, can create layout shifts; the &lt;abbr title=&#34;Web Incubator Community Group&#34;&gt;WICG&lt;/abbr&gt;&amp;rsquo;s &lt;cite&gt;&lt;a href=&#34;https://wicg.github.io/layout-instability/#sec-intro&#34;&gt;Layout Instability API&lt;/a&gt;&lt;/cite&gt; describes the phenomenon in detail. Avoid layout shifts by including dimensions in HTML attributes. The simplest way to do so is by including unitless &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; values, but the &lt;code&gt;style&lt;/code&gt; attribute could work too. I recommend staying away from the &lt;code&gt;style&lt;/code&gt; attribute, or at least selectively allowing its use with the &lt;code&gt;style-src-attr&lt;/code&gt; CSP directive.&lt;/p&gt;
&lt;h3 id=&#34;other-server-side-tweaks&#34;&gt;Other server-side tweaks&lt;/h3&gt;
&lt;p&gt;In-depth server configuration is a bit out of scope, so I&amp;rsquo;ll keep each improvement brief.&lt;/p&gt;
&lt;p&gt;Compression&amp;mdash;especially static compression&amp;mdash;dramatically reduces download sizes. My full-text Atom feed is almost a megabyte, but the Brotli-compressed version is under one-quarter of that size. Caddy supports this with a &lt;code&gt;precompressed&lt;/code&gt; directive; Nginx requires the &lt;a href=&#34;https://github.com/google/ngx_brotli&#34;&gt;ngx_brotli module&lt;/a&gt; for Brotli compression.&lt;/p&gt;
&lt;p&gt;When serving many resources at once (e.g., if a page has many images), HTTP/2 could offer a speed boost through multiplexing; use it if you can, but expect many clients to only support HTTP/1.1. HTTP/3 is unlikely to help textual websites much, so run a benchmark to see if it&amp;rsquo;s worthwhile.&lt;/p&gt;
&lt;p&gt;Consider caching static assets indefinitely with a year-long duration in their &lt;code&gt;cache-control&lt;/code&gt; headers, possibly with an &lt;code&gt;immutable&lt;/code&gt; parameter. If you have to update a static asset, cache-bust it by altering the URL. This approach should eliminate the need for an &lt;code&gt;etag&lt;/code&gt; header on static assets.&lt;/p&gt;
&lt;p&gt;Using &lt;a href=&#34;https://en.wikipedia.org/wiki/OCSP_stapling&#34;&gt;OCSP stapling&lt;/a&gt; eliminates the need to connect to a certificate authority, saving users a DNS lookup and allowing them to instead re-use a connection.&lt;/p&gt;
&lt;p&gt;Consider the trade-offs involved in enabling 0-&lt;abbr title=&#34;Round-Trip Time&#34;&gt;RTT&lt;/abbr&gt; for TLS 1.3. On one hand, it shaves off a round-trip during session resumption; on the other hand, it can enable replay attacks. 0-RTT shouldn&amp;rsquo;t be too unsafe for idempotent GET requests of static content. For dynamic content, evaluate whether your backend is vulnerable to replay attacks described in &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc8446.html#appendix-E.5&#34;&gt;appendix E.5&lt;/a&gt; of the spec.&lt;/p&gt;
&lt;h2 id=&#34;against-lazy-loading&#34;&gt;Against lazy loading&lt;/h2&gt;
&lt;p&gt;Lazy loading may or may not work. Some browsers, including Firefox and the Tor Browser, disable lazy-loading when the user turns off JavaScript. Turning it off makes sense because lazy-loading, like JavaScript, is a fingerprinting vector. Specifically, it identifies idiosyncratic scrolling patterns.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
	&lt;p&gt;Loading is only deferred when JavaScript is enabled. This is an anti-tracking measure, because if a user agent supported lazy loading when scripting is disabled, it would still be possible for a site to track a user’s approximate scroll position throughout a session, by strategically placing images in a page’s markup such that a server can track how many images are requested and when.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img&#34;&gt;&amp;lt;img&amp;gt;: The Image Embed element&lt;/a&gt;&lt;/cite&gt; on &lt;abbr title=&#34;Mozilla Developer Network&#34;&gt;MDN&lt;/abbr&gt;, &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading&#34;&gt; the &lt;code&gt;loading&lt;/code&gt; attribute&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If you can&amp;rsquo;t rely on lazy loading, your pages should work well without it. If pages work well without lazy loading, is it worth enabling?&lt;/p&gt;
&lt;p&gt;The scope of this article is textual content supplemented by images. In that context, I don&amp;rsquo;t think lazy loading is worthwhile because it often frustrates users on slow connections. I think I can speak for some of these users: mobile data near my home has a number of &amp;ldquo;dead zones&amp;rdquo; with abysmal download speeds, and my home&amp;rsquo;s Wi-Fi repeater setup used to result in packet loss rates surpassing 60% (!!).&lt;/p&gt;
&lt;p&gt;Users on poor connections have better things to do than idly wait for pages to load. They might open multiple links in background tabs to wait for them all to load at once, and/or switch to another task and come back when loading finishes. They might also open links while on a good connection before switching to a poor connection. For example, I often open several links on Wi-Fi before going out for a walk in a mobile-data dead-zone. A Reddit user reading an earlier version of this article described a &lt;a href=&#34;https://i.reddit.com/r/web_design/comments/k0dmpj/an_opinionated_list_of_best_practices_for_textual/gdmxy4u/&#34;&gt;similar experience riding the train&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, pages with lazy loading don&amp;rsquo;t finish loading off-screen images in the background. To load this content ahead of time, users need to switch to the loading page and slowly scroll to the end to ensure that all the important content appears on-screen and starts loading. Website owners shouldn&amp;rsquo;t expect users to have to jump through these ridiculous hoops.&lt;/p&gt;
&lt;h3 id=&#34;against-speculative-pre-loading&#34;&gt;Against speculative pre-loading&lt;/h3&gt;
&lt;p&gt;&lt;ins&gt;Update &lt;time&gt;2024-04-06&lt;/time&gt;: I&amp;rsquo;ve updated my stance on this. If you use the &lt;a href=&#34;https://wicg.github.io/nav-speculation/speculation-rules.html&#34;&gt;Speculation Rules API&lt;/a&gt;, preloading will obey user preferences in a standard cross-site way.&lt;/ins&gt;&lt;/p&gt;
&lt;p&gt;A common objection to my case against lazy-loading is that users may be more likely to click a link than scroll to the end, so pages should prioritize pre-loading the link. Pre-loading a page&amp;rsquo;s essential resources is fine. Speculatively pre-loading content on separate pages isn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Many users with poor connections also have capped data, and would prefer that pages don&amp;rsquo;t decide to predictively load many pages ahead-of-time for them. The overlap between these two groups grows especially pronounced as data cap overages trigger throttling; this is enough to trigger &lt;a href=&#34;https://web.archive.org/web/20220402004738/https://nitter.pussthecat.org/yoavweiss/status/1195036487538003968&#34;&gt;a seasonal pattern in Japan&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some go so far as to disable this behavior to avoid data overages. Savvy privacy-conscious users (including Tor Browser users) also generally disable speculative pre-loading since pre-loading behavior is fingerprintable.&lt;/p&gt;
&lt;p&gt;Users who click a link choose to download its contents, &lt;a href=&#34;#transfer-size-and-user-flows&#34;&gt;within a reasonable size limit&lt;/a&gt;. Loading pages that a user hasn&amp;rsquo;t navigated to is making a choice for that user. I encourage adoption of &amp;ldquo;link&amp;rdquo; HTTP headers to pre-load essential and above-the-fold resources when possible, but doing so does not resolve the issues with lazy-loading: the people who are harmed by lazy loading are more likely to have pre-fetching disabled.&lt;/p&gt;
&lt;p&gt;Moreover, determining the pages to prioritize for speculative pre-loading typically requires analytics and/or A/B testing. Enrolling users in a study (e.g. by collecting information about their behavior) without prior informed consent &lt;em&gt;in terms they fully understand&lt;/em&gt; demonstrates a disrespect for their autonomy. Furthermore: analytics typically represent all users equally, when developers should be giving disproportionate attention to marginalized users (e.g., disabled users). The convenience of the majority should not generally outweigh the needs of the minority. Many marginalized groups don&amp;rsquo;t wish to broadcast the fact that they have special needs, so don&amp;rsquo;t rely on being able to figure out who&amp;rsquo;s whom.&lt;/p&gt;
&lt;h3 id=&#34;cant-users-on-poor-connections-disable-images&#34;&gt;Can&amp;rsquo;t users on poor connections disable images?&lt;/h3&gt;
&lt;p&gt;I have two responses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If an image isn&amp;rsquo;t essential, don&amp;rsquo;t include it in the page. If an image is essential, assume sighted users want to see it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Yes, users could disable images. That&amp;rsquo;s &lt;em&gt;their&lt;/em&gt; choice. If your page uses lazy loading, you&amp;rsquo;ve effectively (and probably unintentionally) made that choice for a large number of users.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Nonetheless, expect some readers to have images disabled. Refer to &lt;a href=&#34;#beyond-alt-text&#34;&gt;the &amp;ldquo;Beyond alt-text&amp;rdquo; section&lt;/a&gt; to see how to best support this case.&lt;/p&gt;
&lt;h3 id=&#34;related-issues&#34;&gt;Related issues&lt;/h3&gt;
&lt;p&gt;Pages should finish making all &lt;code&gt;GET&lt;/code&gt; network requests while loading. This makes it easy to load pages in the background before disconnecting. I singled out lazy-loading, but other factors can violate this constraint.&lt;/p&gt;
&lt;p&gt;One example is pagination. It&amp;rsquo;s easier to download one long article ahead of time, but inconvenient to load each page separately. Displaying content all at once also improves searchability. The single-page approach has obvious limits: don&amp;rsquo;t expect users to happily download a single-page novel.&lt;/p&gt;
&lt;p&gt;Another common offender is infinite-scrolling. In addition to requiring JavaScript, infinite-scrolling also makes it difficult for readers to find their old place upon re-visiting a page. This creates harsh consequences for accidental navigation. WordPress documentation lists &lt;a href=&#34;https://make.wordpress.org/accessibility/handbook/markup/infinite-scroll/&#34;&gt;more problems with infinite scrolling&lt;/a&gt;.&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A hybrid between the two is paginated content in which users click a &amp;ldquo;load next page&amp;rdquo; link to insert the next page at the end of the current page (typically using &amp;ldquo;dynamic content replacement&amp;rdquo;). It&amp;rsquo;s essentially the same as infinite scrolling, except additional content is loaded after a click rather than by scrolling. This is only slightly less bad than infinite scrolling; it still has the same fundamental issue of allowing readers to lose their place.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve discussed loading pages in the background, but what about saving a page offline (e.g. with &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;s&lt;/kbd&gt;)? While lazy-loading won&amp;rsquo;t interfere with the ability to save a complete page offline, some of these related issues can. Excessive pagination and inline scrolling make it impossible to download a complete page without manually scrolling or following pagination links to the end.&lt;/p&gt;
&lt;hr /&gt;
&lt;section
	aria-label=&#34;comic, caption, and transcript&#34;
	
	id=&#34;xkcd-1309&#34; tabindex=&#34;-1&#34;&gt;
&lt;h4 id=&#34;infinite-scrolling&#34;&gt;&lt;span&gt;xkcd comic: infinite scrolling&lt;/span&gt;&lt;/h4&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/infinite_scrolling_dark.1985562808.jxl&#34;
type=&#34;image/jxl&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/infinite_scrolling_dark.2523435962.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/infinite_scrolling_dark.872530919.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/infinite_scrolling.1312085072.jxl&#34;
type=&#34;image/jxl&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/infinite_scrolling.2120681135.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/infinite_scrolling.2588509893.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;249&#34; height=&#34;348&#34;
src=&#34;https://envs.net/~seirdy/p/infinite_scrolling.2588509893.png&#34; alt=&#34;Comic: infinite-scrolling books need careful handling to avoid losing the page.&#34;
aria-describedby=&#34;transcript-xkcd-1309&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Infinite-scroll means that accidental navigation to a link results in losing your place. From &lt;a href=&#34;https://xkcd.com/1309/&#34;&gt;xkcd&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;details&gt;
&lt;summary&gt;Toggle comic &lt;span&gt;transcript&lt;/span&gt;&lt;/summary&gt;
&lt;section id=&#34;transcript-xkcd-1309&#34;&gt;
&lt;h5&gt;Comic transcript&lt;/h5&gt;
	&lt;div&gt;
		&lt;p&gt;Megan stands at a desk, touching a book gingerly. Cueball stands behind her.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Cueball&lt;/dt&gt;
&lt;dd&gt;Why are you turning the pages like that?&lt;/dd&gt;
&lt;dt&gt;Megan&lt;/dt&gt;
&lt;dd&gt;If I touch the wrong thing, I&amp;rsquo;ll lose my place and have to start over.&lt;/dd&gt;
&lt;dt&gt;Caption below the panel&lt;/dt&gt;
&lt;dd&gt;If books worked like infinite-scrolling webpages&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/details&gt;

&lt;/section&gt;
&lt;hr /&gt;

&lt;h2 id=&#34;long-page-performance&#34;&gt;Long-page performance&lt;/h2&gt;
&lt;p&gt;Deferring network requests is a bad idea, as established in the &lt;a href=&#34;#against-lazy-loading&#34;&gt;previous &amp;ldquo;Against lazy loading&amp;rdquo; section&lt;/a&gt;. There are other ways to improve large-page performance.&lt;/p&gt;
&lt;p&gt;An alternative to the &lt;code&gt;loading&lt;/code&gt; attribute that I &lt;em&gt;do&lt;/em&gt; recommend is the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#attr-decoding&#34;&gt;&lt;code&gt;decoding&lt;/code&gt; attribute&lt;/a&gt;. I typically use &lt;code&gt;decoding=&amp;quot;async&amp;quot;&lt;/code&gt; so that image decoding can be deferred.&lt;/p&gt;
&lt;h3 id=&#34;css-containment&#34;&gt;CSS containment&lt;/h3&gt;
&lt;p&gt;Long pages with many DOM nodes may benefit from CSS containment, a more recently-adopted part of the CSS specification.&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;dfn&gt;CSS containment&lt;/dfn&gt; allows authors to isolate sub-trees of the DOM. This lets browsers make more informed optimizations: they can delay painting off-screen content or reduce re-calculations when isolated nodes change. Combined with a property like &lt;code&gt;content-visibility&lt;/code&gt;, it enables browsers to defer all rendering of less essential below-the-fold content.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;content-visibility: auto&lt;/code&gt; is a more complex directive than &lt;code&gt;content-visibility: hidden&lt;/code&gt;; rather than being similar to &lt;code&gt;display: none&lt;/code&gt;, it adaptively hides/&lt;wbr /&gt;displays an element&amp;rsquo;s contents as they become &lt;a href=&#34;https://drafts.csswg.org/css-contain/#relevant-to-the-user&#34;&gt;relevant to the user&lt;/a&gt;. It also doesn’t hide its &lt;a href=&#34;https://drafts.csswg.org/css-contain/#skips-its-contents&#34;&gt;skipped contents&lt;/a&gt; from the user agent, so screen readers, in-page search, and other tools can still interact with it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;CSS Containment Module Level 2&lt;/cite&gt;, section 4.2:
&lt;a class=&#34;u-url&#34; href=&#34;https://drafts.csswg.org/css-contain/#using-cv-auto&#34;&gt;Using &lt;code&gt;content-visibility: auto&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Leveraging containment and &lt;code&gt;content-visibility&lt;/code&gt; is a progressive enhancement, so there aren&amp;rsquo;t any serious implications for older browsers. I use &lt;code&gt;content-visibility&lt;/code&gt; to defer rendering off-screen entries in my archives. Doing so allows me to serve long archive pages instead of resorting to pagination, with page-length limited only by download size. In my tests using Lighthouse with Chromium Devtools&amp;rsquo; simulated CPU throttling,&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; this article rendered faster &lt;em&gt;with&lt;/em&gt; containment-enabled CSS than without any custom stylesheets at all.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;content-visibility&lt;/code&gt; for content at the end of the page is relatively safe. Using it for content earlier in the page risks introducing minor &lt;a href=&#34;#layout-shifts&#34;&gt;layout shifts&lt;/a&gt; and scrollbar-jumping. Eliminate the layout shifts by calculating a value for the &lt;code&gt;contain-intrinsic-size&lt;/code&gt; property. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.terluinwebdesign.nl/en/css/calculating-contain-intrinsic-size-for-content-visibility/&#34;&gt;Calculating ‘contain-intrinsic-size’ for ‘content-visibility’&lt;/a&gt;&lt;/cite&gt;, by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.terluinwebdesign.nl/en/about-us/thijs-terluin/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Thijs&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Terluin&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
from &lt;span class=&#34;p-org org&#34;&gt;
&lt;a class=&#34;organization-name&#34; href=&#34;https://www.terluinwebdesign.nl/en/&#34;&gt;
&lt;span&gt;Teluin Webdesign&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, is a comprehensive guide to calculating intrinsic size values. The scrollbar is less likely to jump around noticeably on extra-long pages, so sufficient page-length could let you get away with setting &lt;code&gt;contain-intrinsic-size&lt;/code&gt; to a rough estimate.&lt;/p&gt;
&lt;h3 id=&#34;performance-of-assistive-technologies&#34;&gt;Performance of assistive technologies&lt;/h3&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://ericwbailey.design/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Eric&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Bailey&lt;/span&gt;&lt;/span&gt;’s&lt;/a&gt;&lt;/span&gt; presentation &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://noti.st/ericwbailey/Yfyaxa/slides&#34;&gt;The intersection of performance and accessibility&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; describes how computing the accessibility tree can be expensive if a page has too many DOM nodes and custom elements. Browsers use complex heuristics to determine which elements to report, to reduce the size of the accessibility tree. Now that all major browsers are moving to multi-process architectures, some browser components interface with assistive technology (&lt;abbr title=&#34;Assistive Technology&#34;&gt;AT&lt;/abbr&gt;) in a separate process. Data about the page&amp;rsquo;s semantics needs to cross process boundaries, incurring additional overhead.&lt;/p&gt;
&lt;p&gt;Re-calculating nodes in the accessibility tree can create small delays for user interaction. These delays add up, causing the accessibility tree to fall out-of-sync with the actual page state. In extreme cases, an out-of-control accessibility tree may crash the &lt;abbr&gt;AT&lt;/abbr&gt;. Moreover, speech synthesizers may be slow to start speaking when the CPU is under load. Delayed speech synthesis is incredibly annoying because it tends to omit words while &amp;ldquo;warming up&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;When pages grow long, keep performance in check by doing the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Prefer semantic HTML over custom elements. The browser&amp;rsquo;s accessibility-tree-generation and element-filtering is optimized for semantic HTML; it has to do more guesswork to decipher custom elements.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid scripts that delay user-input or cause complex DOM mutations. These will introduce delays that can cause significant &lt;abbr&gt;AT&lt;/abbr&gt; usability issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remember that CSS can impact the accessibility tree. Avoid using scripts to alter properties such as &lt;code&gt;display&lt;/code&gt; and &lt;code&gt;visibility&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test with screen readers on underpowered hardware. Examples include old entry-level Android phones and netbooks with aggressive thermal throttling.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;old-browsers&#34;&gt;Old browsers&lt;/h2&gt;
&lt;p&gt;People do not use your site exclusively with the latest stable versions of Chrome, Firefox, or Safari. If you use metrics, they will be biased against users who avoid your site due to incompatibilities.&lt;/p&gt;
&lt;h3 id=&#34;old-browsers-in-use&#34;&gt;Old browsers in use&lt;/h3&gt;
&lt;p&gt;Plenty of reasons exist for using older versions of each of the mainstream browsers:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Firefox&lt;/dt&gt;
&lt;dd&gt;In addition to Firefox&amp;rsquo;s &amp;ldquo;Stable&amp;rdquo;, &amp;ldquo;Beta&amp;rdquo;, and &amp;ldquo;Nightly&amp;rdquo; channels, Firefox includes an &amp;ldquo;Extended Support Release&amp;rdquo; (&lt;abbr title=&#34;Extended Support Release&#34;&gt;ESR&lt;/abbr&gt;). Firefox &lt;abbr&gt;ESR&lt;/abbr&gt; receives only bugfixes and major security patches for over one year. It&amp;rsquo;s the default browser in Debian and the basis for the Tor Browser. In other words: if you want people to be able to browse your site anonymously (i.e. with the Tor Browser), you need to support Firefox &lt;abbr&gt;ESR&lt;/abbr&gt; versions for over 15 months after their release (sometimes longer&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;). If that wasn&amp;rsquo;t enough: the latest version of KaiOS uses Firefox 84, while older versions (still being sold in 2022!) use Firefox 49.&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;dt&gt;Safari and WebKit&lt;/dt&gt;
&lt;dd&gt;On Linux, WebKitGTK powers various browsers, RSS readers, and in-app browsers. WebKitGTK versions are limited by a distribution&amp;rsquo;s release model; LTS distributions will not have the shiniest new WebKit features. Safari versions are similarly limited by iOS and macOS versions. For instance, the iPhone 7 will not be able to run iOS 16 or Safari 16, just four years after it was discontinued; it&amp;rsquo;ll only receive occasional security patches for Safari 15.x. The only way for iPhone-7-and-earlier users to use Safari 16+ features is to buy a new phone. Expecting users to buy a new device every few years just to display a webpage needlessly contributes to the rampant consumerism and throw-away culture in the consumer electronics industry.&lt;/dd&gt;
&lt;dt&gt;Chromium&lt;/dt&gt;
&lt;dd&gt;&lt;a href=&#34;https://support.google.com/chrome/a/answer/9027636?hl=en&#34;&gt;Google Chrome&amp;rsquo;s &amp;ldquo;Extended stable&amp;rdquo; channel&lt;/a&gt; releases half as often as its &amp;ldquo;Stable&amp;rdquo; channel. Moreover, Chromium is the basis for QtWebEngine, the Web engine of the Qt UI toolkit. QtWebEngine powers a host of Web browsers: Qutebrowser, Falkon, Nyxt, Angelfish, Otter Browser, and others. Like WebKit2GTK, QtWebEngine powers various RSS readers and in-app browsers. The latest version of Qt typically includes a QtWebEngine several versions behind upstream Chromium, and most distributions don&amp;rsquo;t ship the latest version of Qt. Finally, Android&amp;rsquo;s Chromium-based WebView implementations are still sometimes locked to a vendor&amp;rsquo;s abandoned version of Android and woefully out of date; in-app browsers are often even worse, sometimes shipping a version of Chromium that&amp;rsquo;s &lt;em&gt;years&lt;/em&gt; old.&lt;/dd&gt;
&lt;dt&gt;Opera&lt;/dt&gt;
&lt;dd&gt;Opera switched away from its in-house Presto browser engine a few years ago, in favor of becoming a Chromium fork. However, Opera Presto is still being kept alive by Opera Mini. Opera Mini&amp;rsquo;s &amp;ldquo;extreme&amp;rdquo; mode uses a proxy server to render pages; that server runs Opera&amp;rsquo;s Presto rendering engine, which hasn&amp;rsquo;t added new Web standards in years.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;how-to-support-old-browsers&#34;&gt;How to support old browsers&lt;/h3&gt;
&lt;p&gt;I recommend testing with a pre-2013 version of WebKit, as those WebKit versions are ancestors to both Chromium and Safari. Old versions of Opera and Firefox are still available for download. Obviously, I wouldn&amp;rsquo;t recommend using these browsers outside of a heavily sandboxed environment (e.g. a confined VM) unless you disable unnecessary features and limit their use to testing.&lt;/p&gt;
&lt;p&gt;Always use progressive enhancement: everything besides your semantic markup and the occasional legacy image format should be an optional enhancement. Test with CSS, scripts, new image formats, etc. disabled.&lt;/p&gt;
&lt;p&gt;Restrict markup to the subset of the WHATWG&amp;rsquo;s HTML Living Standard that also appears in the W3C&amp;rsquo;s HTML 5.1 standard. This should provide a slower-moving base than the raw Living Standard that&amp;rsquo;s also friendlier to older browsers. I don&amp;rsquo;t recommend referencing the W3C&amp;rsquo;s HTML 5.1 standard directly, since the Living Standard has since made several important clarifications, corrections, and removals.&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;CSS offers multiple equivalent ways to do the same thing; prefer older versions when possible. A non-exhaustive list of ways to make stylesheets work in older browsers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use &lt;code&gt;em&lt;/code&gt; units rather than the more convenient &lt;code&gt;rem&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid CSS variables and custom properties; keep track of values by using increments, or use a post-processor to replace references to variables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the &lt;code&gt;@supports&lt;/code&gt; at-rule to progressively replace an older feature with a newer one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explicitly define the &lt;code&gt;display&lt;/code&gt; property for the &lt;code&gt;hidden&lt;/code&gt; attribute, for browsers that don&amp;rsquo;t support &lt;code&gt;hidden&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When in doubt: &lt;a href=&#34;https://caniuse.com/&#34;&gt;Can I Use&lt;/a&gt; and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/MDN/Writing_guidelines/Page_structures/Compatibility_tables&#34;&gt;MDN&amp;rsquo;s browser compatibility data&lt;/a&gt; are excellent resources to track feature support across all the mainstream browser engines.&lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt; Feel free to go wild when adding strictly-optional features.&lt;/p&gt;
&lt;h2 id=&#34;the-tor-browser&#34;&gt;The Tor Browser&lt;/h2&gt;
&lt;p&gt;Many people use Tor out of necessity. On Tor, additional constraints apply.&lt;/p&gt;
&lt;h3 id=&#34;constraints-of-the-tor-browser&#34;&gt;Constraints of the Tor Browser&lt;/h3&gt;
&lt;p&gt;Tor users are encouraged to set the &lt;a href=&#34;https://tb-manual.torproject.org/en-US/security-settings/&#34;&gt;Tor Browser&amp;rsquo;s security settings&lt;/a&gt; to &amp;ldquo;safest&amp;rdquo;. This disables scripts, MathML, remote fonts, SVG images, and &lt;a href=&#34;https://gitweb.torproject.org/tor-browser.git/tree/browser/components/securitylevel/SecurityLevel.jsm?id=ffdf16f3e8a44b306abd988be874a184b7de1cc6#n273&#34;&gt;other unsafe Firefox features&lt;/a&gt;. If your site has any SVG images, the Tor browser will download these just like Firefox would (to avoid fingerprinting) but will not render them.&lt;/p&gt;
&lt;p&gt;If you must use scripts, ensure that they perform well with just-in-time (&lt;abbr title=&#34;Just-In-Time&#34;&gt;JIT&lt;/abbr&gt;) compilation disabled. The Tor Browser&amp;rsquo;s &amp;ldquo;safer&amp;rdquo; mode, iOS Lockdown mode, and Microsoft Edge&amp;rsquo;s &amp;ldquo;enhanced&amp;rdquo; security mode all disable JIT compilation by default.&lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Additionally, hopping between nodes in Tor circuits incurs latency, worsening the impacts of requiring multiple requests and round-trips. Try to minimise the number of requests to view a page.&lt;/p&gt;
&lt;p&gt;If you use a CDN or some overcomplicated website security stack, make sure it doesn&amp;rsquo;t block Tor users or require them to enable JavaScript to complete a CAPTCHA. Tor Browser users are supposed to avoid fingerprinting vectors like JS and browser extensions, so requiring a JavaScript-&lt;wbr /&gt;based CAPTCHA will effectively block many Tor users.&lt;/p&gt;
&lt;p&gt;Tor users are unable to leverage media queries or client-hints to signal special needs. Pages need to be as accessible as possible by default, as per the &lt;a href=&#34;#inc-by-default&#34;&gt;&amp;ldquo;inclusive by default&amp;rdquo; directive outlined earlier&lt;/a&gt;. This should be a given, but it&amp;rsquo;s doubly important when serving fingerprinting-averse readers.&lt;/p&gt;
&lt;h3 id=&#34;hidden-services&#34;&gt;Hidden services&lt;/h3&gt;
&lt;p&gt;To go above and beyond, try mirroring your site to a Tor hidden service to reduce the need for exit nodes. Mirroring allows you to keep a separate version of your site optimized for the Tor browser.&lt;/p&gt;
&lt;p&gt;Normally, optimizing specifically for a given user agent&amp;rsquo;s quirks (especially in a separate version of a website) is a bad practice; however, the Tor Browser is a special case because there&amp;rsquo;s no alternative available: Tor users should all use the same browser to avoid standing out. Sometimes, the Tor Browser pretends to have Firefox&amp;rsquo;s capabilities: progressive enhancement and graceful degradation won&amp;rsquo;t work when a browser lies about its functionality.&lt;/p&gt;
&lt;p&gt;For example, my website&amp;rsquo;s clearnet version uses some SVG images. Some browsers can&amp;rsquo;t handle a given image format. The typical solution is to use a &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element containing &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; children of varying formats and a fallback &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element using a legacy image format.&lt;/p&gt;
&lt;p&gt;The Tor browser will download whichever format Firefox would, rather than whichever formats it actually supports. A &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element containing an SVG and a raster fallback won&amp;rsquo;t help: the Tor browser will avoid fingerprinting by selecting the SVG format, not a fallback format. The image will not be rendered, so users will have downloaded the image only to see a white box.&lt;/p&gt;
&lt;p&gt;I address the issue by not using any SVG images on &lt;a href=&#34;http://wgq3bd2kqoybhstp77i3wrzbfnsyd27wt34psaja4grqiezqircorkyd.onion/&#34;&gt;my hidden service&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;in-page-search&#34;&gt;In-page search&lt;/h2&gt;
&lt;p&gt;In-page search (e.g., using &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;f&lt;/kbd&gt;) has been a basic feature in document readers well before browsers, and continues to be an essential feature today.&lt;/p&gt;
&lt;p&gt;Searchability is a good reason to prefer conveying information textually, when possible: video (especially without accurate captions), pictures of text, etc. aren&amp;rsquo;t so easily searchable.&lt;/p&gt;
&lt;p&gt;Web pages that hide content behind &amp;ldquo;show content&amp;rdquo; widgets are difficult to search through: users need to toggle &amp;ldquo;show content&amp;rdquo; for each item they wish to search. Often, in-page search highlights are hidden; &lt;a href=&#34;#reddit-redesign&#34;&gt;Reddit&amp;rsquo;s atrocious redesign&lt;/a&gt; is a serious offender. If you need to hide some content for performance reasons, I described a less hostile way to do so in &lt;a href=&#34;#long-page-performance&#34;&gt;the &amp;ldquo;Long-page performance&amp;rdquo; section&lt;/a&gt;.&lt;/p&gt;
&lt;figure id=&#34;reddit-redesign&#34; tabindex=&#34;-1&#34;&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/find_dark.2440236660.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/find_dark.3786093455.webp&#34;
type=&#34;image/webp&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/find_dark.2931746396.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/find.1996717779.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/find.3761549111.webp&#34;
type=&#34;image/webp&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/find.1285370450.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;426&#34; height=&#34;316&#34;
src=&#34;https://envs.net/~seirdy/p/find.1285370450.png&#34; alt=&#34;screenshots before/after clicking a “see more” link obscuring a search match.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Searching for the word &amp;ldquo;good&amp;rdquo; before and after a &amp;ldquo;see more&amp;rdquo; link is clicked. Both situations show a match, but only one of them allows us to view the match. Both screenshots are from the Reddit redesign.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;the-importance-of-proofreading&#34;&gt;The importance of proofreading&lt;/h3&gt;
&lt;p&gt;Correct, consistent spelling is important to readers who use search. In-page search doesn&amp;rsquo;t currently pick up misspelled words. If in-page search implementations develop such a feature, some users may wish to sometimes turn it off; even Google Search implemented a &amp;ldquo;verbatim&amp;rdquo; mode for exact matches.&lt;/p&gt;
&lt;p&gt;Moreover, some search implementations (such as the one built into Firefox) support case-sensitive matching. Inconsistent capitalization of proper nouns, acronyms, and initialisms can make searching difficult.&lt;/p&gt;
&lt;h3 id=&#34;problematic-overrides&#34;&gt;Problematic overrides&lt;/h3&gt;
&lt;p&gt;Search is so essential to some users&amp;rsquo; ability to navigate that some desktop users enable &amp;ldquo;type-ahead&amp;rdquo; search, to automatically begin a search upon typing multiple characters.&lt;sup id=&#34;fnref:17&#34;&gt;&lt;a href=&#34;#fn:17&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;17&lt;/a&gt;&lt;/sup&gt; If you ignored my advice to avoid JavaScript, at least think twice before using it to define custom keyboard shortcuts which interfere with this type of functionality. I singled out type-ahead search, but there are countless other examples of uncommon keyboard behavior that JavaScript overrides interfere with.&lt;/p&gt;
&lt;p&gt;Another problematic override is scroll-behavior. Enforcing smooth-scrolling (e.g., with the &lt;code&gt;scroll-behavior&lt;/code&gt; CSS property) can interfere with the use of in-page search by slowing down jumps between matches. Rapidly darting around the page with smooth scrolling can cause motion sickness. Simply relying on users to override default behaviors violates the &amp;ldquo;inclusive by default&amp;rdquo; directive I encourage, since user preferences are fingerprintable and shift responsibility away from developers.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s a complex solution to &lt;a href=&#34;https://schepp.dev/posts/smooth-scrolling-and-page-search/&#34;&gt;turn off smooth scrolling for un-focused elements&lt;/a&gt;, but it doesn&amp;rsquo;t address separate issues such as anchor-link navigation.&lt;/p&gt;
&lt;h2 id=&#34;about-fonts&#34;&gt;About fonts&lt;/h2&gt;
&lt;p&gt;I recommend setting the default font to &lt;code&gt;sans-serif&lt;/code&gt;. &lt;a href=&#34;https://infinnie.github.io/blog/2017/systemui.html&#34;&gt;&lt;code&gt;system-ui&lt;/code&gt; causes issues&lt;/a&gt; among readers whose system fonts don&amp;rsquo;t cover your website&amp;rsquo;s charset.&lt;/p&gt;
&lt;p&gt;If you really want, you could use serif instead of sans-serif; however, serif fonts tend to look worse on low-res monitors. Not every screen&amp;rsquo;s &lt;abbr title=&#34;Dots Per Inch&#34;&gt;DPI&lt;/abbr&gt; has three digits. Accommodate users&amp;rsquo; default zoom levels by keeping your font size the same as most similar websites.&lt;/p&gt;
&lt;p&gt;To ship custom fonts is to assert that branding is more important than user choice. That might very well be a reasonable thing to do; branding isn&amp;rsquo;t evil! That being said, textual websites in particular don&amp;rsquo;t benefit much from branding. Beyond basic layout and optionally supporting dark mode, authors generally shouldn&amp;rsquo;t dictate the presentation of their websites; that should be the job of the user agent. Most websites are not important enough to look completely different from the rest of the user&amp;rsquo;s system.&lt;/p&gt;
&lt;p&gt;A personal example: I set my preferred browser font to &lt;code&gt;sans-serif&lt;/code&gt;, and map it to my preferred font in my computer&amp;rsquo;s fontconfig settings. Now every website that uses sans-serif will have my preferred font. Sites with sans-serif blend into the users&amp;rsquo; systems instead of sticking out.&lt;/p&gt;
&lt;h3 id=&#34;but-most-users-dont-change-their-fonts&#34;&gt;But most users don&amp;rsquo;t change their fonts&amp;hellip;&lt;/h3&gt;
&lt;p&gt;The &amp;ldquo;users don&amp;rsquo;t know better and need us to make decisions for them&amp;rdquo; mindset isn&amp;rsquo;t without merits; however, in my opinion, it&amp;rsquo;s overused. Using system fonts doesn&amp;rsquo;t make your website harder to use, but it does make it smaller and stick out less to the subset of users who care enough about fonts to change them. This argument isn&amp;rsquo;t about making software easier for non-technical users; it&amp;rsquo;s about branding by asserting a personal preference.&lt;/p&gt;
&lt;p&gt;Moreover, third-party fonts may not always work. The Tor Browser&amp;rsquo;s &amp;ldquo;Safer&amp;rdquo; and &amp;ldquo;Safest&amp;rdquo; modes and iOS 16&amp;rsquo;s &amp;ldquo;Lockdown Mode&amp;rdquo; disable them. Content-blockers like Firefox Focus and uBlock Origin prominently expose remote-font toggles. If you ship remote fonts, you&amp;rsquo;ll need to test your site with remote &lt;em&gt;and&lt;/em&gt; system fonts.&lt;/p&gt;
&lt;h3 id=&#34;stylesheet-overrides-arent-an-excuse&#34;&gt;Style­sheet overrides aren&amp;rsquo;t an excuse&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s not a good idea to require users to automatically override website stylesheets to see their preferred fonts. Doing so would break websites that use fonts such as Font Awesome to display vector icons. We shouldn&amp;rsquo;t have these users constantly battle with websites the same way that many ad- and script-blocking users (myself included) already do when there&amp;rsquo;s a better option.&lt;/p&gt;
&lt;p&gt;That being said, many users &lt;em&gt;do&lt;/em&gt; actually override stylesheets. We shouldn&amp;rsquo;t &lt;em&gt;require&lt;/em&gt; them to do so, but we should keep our pages from breaking in case they do. Pages following this article&amp;rsquo;s advice will probably work perfectly well in these cases without any extra effort.&lt;/p&gt;
&lt;h3 id=&#34;font-fingerprinting-concerns&#34;&gt;Font fingerprinting concerns&lt;/h3&gt;
&lt;p&gt;Some people raised fingerprinting concerns when I suggested using the default &amp;ldquo;sans-serif&amp;rdquo; font. Websites could see which font this maps to in order to identify users.&lt;/p&gt;
&lt;p&gt;You can&amp;rsquo;t do font enumeration or accurately calculate font metrics without JavaScript. Since text-based websites that follow these best-practices don&amp;rsquo;t send requests after the page loads and have no scripts, they shouldn&amp;rsquo;t be able to fingerprint via font identification.&lt;/p&gt;
&lt;p&gt;Other websites can still fingerprint via font enumeration using JavaScript. They don&amp;rsquo;t need to stop at seeing what sans-serif maps to: they can see available fonts on a user&amp;rsquo;s system,&lt;sup id=&#34;fnref:18&#34;&gt;&lt;a href=&#34;#fn:18&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;18&lt;/a&gt;&lt;/sup&gt; the user&amp;rsquo;s canvas fingerprint, window dimensions, etc. Some of these can be mitigated by &lt;a href=&#34;https://support.mozilla.org/en-US/kb/firefox-protection-against-fingerprinting&#34;&gt;Firefox&amp;rsquo;s protections against fingerprinting&lt;/a&gt;, but these protections understandably override user font preferences.&lt;/p&gt;
&lt;p&gt;Ultimately, surveillance self-defense on the web is an arms race full of trade-offs. If you want both privacy and customizability, the web is not the place to look; try Gemini or Gopher instead.&lt;/p&gt;
&lt;h3 id=&#34;zoom-and-font-size&#34;&gt;Zoom and font size&lt;/h3&gt;
&lt;p&gt;Browsers allow users to zoom by adjusting size metrics. Additionally, most browsers allow users to specify a minimum font size. Minimum sizes don&amp;rsquo;t always work; setting size values in &lt;code&gt;px&lt;/code&gt; can override these settings.&lt;/p&gt;
&lt;p&gt;In your stylesheets, avoid using &lt;code&gt;px&lt;/code&gt; where possible. Define sizes and dimensions using relative units (preferably &lt;code&gt;em&lt;/code&gt;). Exceptions exist for rare items that that shouldn&amp;rsquo;t scale with zoom (e.g. decoration, minimum margins).&lt;sup id=&#34;fnref:19&#34;&gt;&lt;a href=&#34;#fn:19&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;19&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-15-caption&#34;&gt;
	&lt;span id=&#34;code-15&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 15&lt;/strong&gt; (&lt;span&gt;CSS&lt;/span&gt;)&lt;/span&gt;:
set font size and line-spacing with a percentage and a unitless value, respectively.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;font: 107.5%/1.5 sans-serif;
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h2 id=&#34;beyond-alt-text&#34;&gt;Beyond alt-text&lt;/h2&gt;
&lt;p&gt;Expect some readers to have images disabled or unloaded. Examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Blind readers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Users with metered connections: sometimes they disable all images, and other times they only disable images surpassing a size.&lt;sup id=&#34;fnref:20&#34;&gt;&lt;a href=&#34;#fn:20&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;20&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;People experiencing packet loss who fail to download some images.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Users of textual browsers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Accordingly, follow good practices for alt-text:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Concisely summarize the image content the best you can, without repeating the surrounding content.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Images should usually have alt-text under 100 ch.&lt;sup id=&#34;fnref:21&#34;&gt;&lt;a href=&#34;#fn:21&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;21&lt;/a&gt;&lt;/sup&gt; Save longer descriptions for a caption or &lt;code&gt;aria-&lt;wbr /&gt;describedby&lt;/code&gt;. Exceptions exist; this is just a weak norm. If longer descriptions elsewhere aren&amp;rsquo;t an option, disregard this advice and make alt-text as long as it needs to be.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don&amp;rsquo;t include significant information that isn&amp;rsquo;t present in the image; I&amp;rsquo;ll cover how to handle supplementary information in the next subsections.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;abbr title=&#34;Web Accessibility Initiative&#34;&gt;WAI&lt;/abbr&gt; provides some guidelines in &lt;cite&gt;&lt;a href=&#34;https://www.w3.org/WAI/tutorials/images/decision-tree/&#34;&gt;An &lt;code&gt;alt&lt;/code&gt; Decision Tree&lt;/a&gt;&lt;/cite&gt;. It&amp;rsquo;s a little lacking in nuance, but makes for a good starting point. Remember that guidelines and &amp;ldquo;good practices&amp;rdquo; always have exceptions.&lt;/p&gt;
&lt;p&gt;Alt text isn&amp;rsquo;t just for blind readers; sighted readers who can&amp;rsquo;t load an image will see alt-text in its place. This alt text might be confined to the image container, so small images should have shorter alt text.&lt;sup id=&#34;fnref:22&#34;&gt;&lt;a href=&#34;#fn:22&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;22&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;putting-images-in-context&#34;&gt;Putting images in context&lt;/h3&gt;
&lt;p&gt;Alt text should be limited to describing content of the image. It lacks context. To make things worse, images can contain a great deal of information. Sighted people can &amp;ldquo;filter&amp;rdquo; this information and find areas to focus on; alt text should capture this detail. However, sighted users&amp;rsquo; understanding of this detail can be informed by surrounding less-essential detail.&lt;/p&gt;
&lt;p&gt;Blind users might struggle to view images in context; they can&amp;rsquo;t easily scan the text before and after an image non-linearly if there&amp;rsquo;s no semantic connection between them. Charles McCathieNevile described this experience by comparing screen reading to &lt;a href=&#34;#straw-analogy&#34;&gt;reading through a drinking straw&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Being sighted and loading images can introduce issues of its own. Sometimes, sighted readers might focus on the &lt;em&gt;wrong&lt;/em&gt; part of an image. How can you give readers the missing context and tell them what to focus on?&lt;/p&gt;
&lt;p&gt;The best solution comes in two parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Before the image, supply context that prepares readers for what to expect.&lt;/li&gt;
&lt;li&gt;After the image, describe your interpretation of important details.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is somewhat similar to the way most students in primary and secondary schools are taught to cite evidence in essays. On that note: remember that these are weak norms, not rules. Deviate where appropriate, just as students should as they learn to write.&lt;/p&gt;
&lt;h3 id=&#34;figures&#34;&gt;Figures&lt;/h3&gt;
&lt;p&gt;A &lt;dfn&gt;figure&lt;/dfn&gt; is any sort of self-contained information that is referenced by&amp;mdash;but somewhat distinct from&amp;mdash;body content. Items that make for good figures are often found in &lt;a href=&#34;https://en.wikipedia.org/wiki/Page_layout#Floating_block&#34;&gt;floating blocks&lt;/a&gt; of print material.&lt;/p&gt;
&lt;p&gt;Consider using a &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; element when employing the previous section&amp;rsquo;s two-part strategy. Place one of the two aforementioned pieces of information in a &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt;; the caption can come before or after the image.&lt;/p&gt;
&lt;p&gt;Figures aren&amp;rsquo;t just for images; they&amp;rsquo;re for any self-contained referenced content that&amp;rsquo;s closer to the surrounding body than an &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;. Some example items that could use a caption:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Blockquote&lt;/dt&gt;
&lt;dd&gt;Captioned with a citation&lt;/dd&gt;
&lt;dt&gt;Code snippet&lt;/dt&gt;
&lt;dd&gt;Captioned with its purpose or a link to the larger file from which the snippet was borrowed&lt;/dd&gt;
&lt;dt&gt;Mathematical notation&lt;/dt&gt;
&lt;dd&gt;Sometimes captioned with a brief explanation of its behavior, purpose, or significance. Remember to add alt-text.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Figures and captions have loose guidelines, and nearly everything I said on the matter is full of exceptions. A figure need not have a caption, but the majority benefit from one. It need not contain a single main element, but most probably should.&lt;/p&gt;
&lt;p&gt;I personally try to maintain the flow of an article even if its figures and captions are completely removed or moved to an appendix. A figure is a &amp;ldquo;self-contained&amp;rdquo; block: user agents may re-position figure captions relative to the main figure content, or move the entire figure elsewhere; this is especially common in &lt;a href=&#34;#non-browsers-reading-mode&#34;&gt;reading-mode implementations&lt;/a&gt;. The HTML specification explicitly notes this behavior; &lt;a href=&#34;https://pandoc.org/&#34;&gt;Pandoc&amp;rsquo;s&lt;/a&gt; HTML-to-LaTeX conversion and &lt;a href=&#34;https://www.printfriendly.com/&#34;&gt;PrintFriendly&lt;/a&gt; are examples of software that moves figure elements around to improve pagination.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
	&lt;p&gt;When a &lt;code&gt;figure&lt;/code&gt; is referred to from the main content of the document by identifying
	it by its caption (e.g., by figure number), it enables such content to be easily moved away from
	that primary content, e.g., to the side of the page, to dedicated pages, or to an appendix,
	without affecting the flow of the document.&lt;/p&gt;
	&lt;p&gt;If a &lt;code&gt;figure&lt;/code&gt; element is referenced by its relative position, e.g.,
	“in the photograph above” or “as the next figure shows” then moving the figure would disrupt the
	page’s meaning. Authors are encouraged to consider using labels to refer to figures, rather than
	using such relative references, so that the page can easily be restyled without affecting the
	page’s meaning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;HTML Living Standard&lt;/cite&gt;, section 4.4.12:
&lt;a class=&#34;u-url&#34; href=&#34;https://html.spec.whatwg.org/multipage/grouping-content.html#the-figure-element&#34;&gt;The &lt;code&gt;figure&lt;/code&gt; element&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;image-transcripts&#34;&gt;Image transcripts&lt;/h3&gt;
&lt;p&gt;Some images contain text. I describe best practices for preparing pictures of text in &lt;a href=&#34;#pictures-of-text&#34;&gt;the &amp;ldquo;Pictures of text&amp;rdquo; section&lt;/a&gt;. Only use pictures of text if the visual appearance of the text is an essential part of what you wish communicate. If the content of the text is also important, include a transcript.&lt;/p&gt;
&lt;p&gt;Image transcripts aren&amp;rsquo;t just useful for the visually impaired; they also help users relying on &lt;a href=&#34;#machine-translation&#34;&gt;machine-translation&lt;/a&gt;, since translation tools rely on textual content. These users won&amp;rsquo;t read alt-text; have an alternative way to discover a transcript.&lt;/p&gt;
&lt;p&gt;If the image is a screenshot of text from a website, link to that website to allow users to read its contents in context; this can serve as an &amp;ldquo;image transcript&amp;rdquo; of sorts.&lt;/p&gt;
&lt;p&gt;A &lt;dfn&gt;&lt;code&gt;longdesc&lt;/code&gt;&lt;/dfn&gt; attribute used to be another way to reference an image transcript. The &lt;code&gt;longdesc&lt;/code&gt; attribute contained a hyperlink (often an anchor link) to a location with more information about an image. This attribute &lt;a href=&#34;https://html.spec.whatwg.org/multipage/obsolete.html#non-conforming-features&#34;&gt;has been obsoleted&lt;/a&gt; in the HTML Living Standard.&lt;/p&gt;
&lt;p&gt;The recommended way to link to a transcript is by hyperlinking the image (i.e., wrapping it with &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;) or semantically grouping the image with its transcript. Put a short summary in the alt-text, and mention the availability of a transcript in a visible caption.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&#34;https://stackoverflow.com/questions/65564539/what-is-the-semantically-correct-way-to-include-transcript-from-a-comic&#34;&gt;StackOverflow thread about comic transcripts&lt;/a&gt; outlines a good approach to semantically grouping images and transcripts, and my approach is similar. I group an image, alt-text, and caption in a &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; element and follow it with a transcript in a &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element. I use &lt;code&gt;aria-&lt;wbr /&gt;describedby&lt;/code&gt; to semantically link the figure and the transcript.&lt;sup id=&#34;fnref:23&#34;&gt;&lt;a href=&#34;#fn:23&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;23&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;An image, alt-text, figure caption, and transcript combine to form a complex relationship that should be grouped together in a single landmark. I put all three inside a &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; with a heading, and give the group an &lt;code&gt;aria-label&lt;/code&gt; that indicates the presence of the three sub-elements. Using a &lt;code&gt;section&lt;/code&gt; landmark ensures that the figure and caption remain together as a single unit. The &lt;a href=&#34;#xkcd-html&#34;&gt;html code&lt;/a&gt; for the &lt;a href=&#34;#infinite-scrolling&#34;&gt;xkcd comic earlier in the page&lt;/a&gt; is a representative example.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;xkcd-html&#34;&gt;
&lt;figcaption id=&#34;xkcd-html-caption&#34;&gt;
	&lt;span id=&#34;xkcd-html&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 16&lt;/strong&gt; (&lt;span&gt;HTML&lt;/span&gt;)&lt;/span&gt;:
here&amp;rsquo;s a simplified version of the HTML used to embed a comic in this article. Of course, I take care of most of the boilerplate with shortcodes.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;section aria-label=&amp;quot;comic, caption, and transcript&amp;quot;&amp;gt;
  &amp;lt;h4&amp;gt;Infinite scrolling&amp;lt;/h4&amp;gt;
  &amp;lt;figure&amp;gt;
    &amp;lt;img src=&amp;quot;SRC&amp;quot;
      aria-describedby=&amp;quot;transcript-xkcd-1309&amp;quot;
      alt=&amp;quot;Comic: infinite-scrolling books require
           careful page-turns to avoid losing the page.&amp;quot;&amp;gt;
    &amp;lt;figcaption&amp;gt;
      Infinite-scroll means that accidental navigation
      to a link results in losing your place.
    &amp;lt;/figcaption&amp;gt;
  &amp;lt;/figure&amp;gt;
  &amp;lt;details&amp;gt;
    &amp;lt;summary&amp;gt;Toggle transcript&amp;lt;/summary&amp;gt;
    &amp;lt;div id=&amp;quot;transcript-xkcd-1309&amp;quot;&amp;gt;
      &amp;lt;p&amp;gt;Megan stands at a desk, touching a book
         gingerly. Cueball stands behind her.&amp;lt;/p&amp;gt;
      &amp;lt;dl&amp;gt;
        &amp;lt;dt&amp;gt;Cueball&amp;lt;/dt&amp;gt;
        &amp;lt;dd&amp;gt;Why are you turning the pages like that?&amp;lt;/dd&amp;gt;
        &amp;lt;dt&amp;gt;Megan&amp;lt;/dt&amp;gt;
        &amp;lt;dd&amp;gt;If I touch the wrong thing, I’ll lose my
            place and have to start over.&amp;lt;/dd&amp;gt;
        &amp;lt;dt&amp;gt;Caption below the panel&amp;lt;/dt&amp;gt;
        &amp;lt;dd&amp;gt;If books worked like infinite-scrolling
            webpages&amp;lt;/dd&amp;gt;
      &amp;lt;/dl&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/details&amp;gt;
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h2 id=&#34;about-custom-colors&#34;&gt;About custom colors&lt;/h2&gt;
&lt;p&gt;Always remember that any color palette you define in your stylesheets is merely a suggestion. Any colors you don&amp;rsquo;t define could fall back to arbitrary defaults; all colors you define could be overridden by the user agent or operating system.&lt;/p&gt;
&lt;h3 id=&#34;default-colors&#34;&gt;Default colors&lt;/h3&gt;
&lt;p&gt;Some users&amp;rsquo; browsers set default page colors that aren&amp;rsquo;t black-on-white. For instance, Linux users who enable GTK style overrides might default to having white text on a dark background. Websites that explicitly set foreground colors but leave the default background color (or vice-versa) end up being difficult to read. The same phenomenon occurs on pages with text foregrounds with image backgrounds.&lt;/p&gt;
&lt;p&gt;A second opinion: &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://utcc.utoronto.ca/~cks/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Chris&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Siebenmann&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; describes this in more detail in &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://utcc.utoronto.ca/~cks/space/blog/web/AWebColoursProblem&#34;&gt;A Web Colours Problem&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. In short: when setting colors, always set both the foreground and the background color. Don&amp;rsquo;t set just one of the two.&lt;/p&gt;
&lt;p&gt;Chris also describes the importance of visited link colors in &lt;cite&gt;&lt;a href=&#34;https://utcc.utoronto.ca/~cks/space/blog/web/VisitedLinksUsability&#34;&gt;Visited Links Usability&lt;/a&gt;&lt;/cite&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;section
	aria-label=&#34;screenshot, caption, and transcript&#34;
	
	id=&#34;better-mf-website&#34; tabindex=&#34;-1&#34;&gt;
&lt;h4 id=&#34;example-unreadable-palette&#34;&gt;Example unreadable palette&lt;/h4&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/website_colors.2502616820.jxl&#34;
type=&#34;image/jxl&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/website_colors.1694928240.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/website_colors.382913732.webp&#34;
type=&#34;image/webp&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/website_colors.635359080.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;400&#34; height=&#34;241&#34;
src=&#34;https://envs.net/~seirdy/p/website_colors.635359080.png&#34; alt=&#34;Gray text on a darker gray background. Details in caption.&#34;
aria-describedby=&#34;transcript-better-mf-website&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;This is an unreadable screenshot of &lt;span class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;http://bettermotherfuckingwebsite.com/&#34;&gt;Better Motherfucking Website&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. I had set my browser foreground and background colors to white and dark gray, respectively. The website overrode the foreground colors while assuming that everyone browses with a white background.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;details&gt;
&lt;summary&gt;Toggle screenshot &lt;span&gt;transcript&lt;/span&gt;&lt;/summary&gt;
&lt;section id=&#34;transcript-better-mf-website&#34;&gt;
&lt;h5&gt;Screenshot transcript&lt;/h5&gt;
	&lt;div&gt;
		&lt;p&gt;A little less contrast.&lt;/p&gt;
&lt;p&gt;Black on white? How often do you see that kind of contrast in real life? Tone it down a bit, asshole. I would&amp;rsquo;ve even made this site&amp;rsquo;s background a nice &lt;code&gt;#EEEEEE&lt;/code&gt; if I wasn&amp;rsquo;t so focused on keeping declarations to a lean 7 fucking lines.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/details&gt;

&lt;/section&gt;
&lt;hr /&gt;

&lt;h3 id=&#34;color-overrides-and-accessibility&#34;&gt;Color overrides and accessibility&lt;/h3&gt;
&lt;p&gt;Even if you set custom colors, ensure that the page is compatible with color overrides: elements shouldn&amp;rsquo;t be distinguished solely by foreground and background color. &lt;a href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/css/C25&#34;&gt;Technique C25&lt;/a&gt; for the &lt;cite&gt;Web Content Accessibility Guidelines (&lt;abbr title=&#34;Web Content Accessibility Guidelines&#34;&gt;WCAG&lt;/abbr&gt;) 2.2&lt;/cite&gt; describes how doing so can meet the WCAG 2.2&amp;rsquo;s &lt;a href=&#34;https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation&#34;&gt;Success Criterion 1.4.8&lt;/a&gt;. Specifically, it describes using default colors in combination with visible borders. The latter helps distinguish elements from surrounding content without relying on a custom color palette.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://seirdy.one/posts/2020/11/23/website-best-practices/&#34;&gt;This page&amp;rsquo;s canonical location&lt;/a&gt; is an example application of Technique C25 (and the related &lt;a href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/general/G148&#34;&gt;Technique G148&lt;/a&gt;). It only uses non-default colors when a user agent requests a dark color scheme (using the &lt;code&gt;prefers-color-scheme&lt;/code&gt; CSS media query; see the next subsection) and for lightening borders. Any image with a solid background may match the page background; to ensure that their dimensions are clear, I surrounded them with borders. Most browsers will render these borders with the default foreground color, which should be visually distinct from the background. I included borders and/or horizontal rules to break up some sections, since heading-based delineation is either unavailable or insufficient for them. When overriding color schemes, the page layout remains clear.&lt;/p&gt;
&lt;p&gt;Color overrides go well beyond simple foreground and background color changes. Windows High Contrast Mode (&lt;abbr title=&#34;Windows High Contrast Mode&#34;&gt;WHCM&lt;/abbr&gt;) is perhaps the best example. &lt;a href=&#34;#win-hcm&#34;&gt;WHCM makes advanced modifications to color palettes&lt;/a&gt;: it colors elements with a user-specified palette, all according to semantic markup while ignoring ARIA overrides.&lt;sup id=&#34;fnref:24&#34;&gt;&lt;a href=&#34;#fn:24&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;24&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;abbr title=&#34;Windows High Contrast Mode&#34;&gt;WHCM&lt;/abbr&gt; leads the standardization process for the &lt;code&gt;forced-colors&lt;/code&gt; CSS media feature, but it isn&amp;rsquo;t the only implementation of the underlying idea. If you navigate to &lt;samp&gt;about:preferences&lt;/samp&gt; in Firefox and activate the &lt;samp translate=&#34;yes&#34;&gt;Colors&lt;/samp&gt; button in the &amp;ldquo;Language and Appearance&amp;rdquo; section, you&amp;rsquo;ll be presented with the option to override website palettes with &lt;a href=&#34;#default-colors&#34;&gt;your own default colors&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Not all approaches completely discard a designer&amp;rsquo;s specified color palette. The CSS Working Group is working on a specification for stylesheet processing in &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://drafts.csswg.org/css-color-adjust-1/&#34;&gt;CSS Color Adjustment Module Level 1&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. The Chromium team&amp;rsquo;s in-progress &lt;a href=&#34;https://chromestatus.com/feature/5672533924773888&#34;&gt;auto dark mode&lt;/a&gt; will use this specification to darken websites globally. Websites can opt out with the &lt;code&gt;color-scheme&lt;/code&gt; property, but they really shouldn&amp;rsquo;t have to: stylesheets should be robust enough to handle re-coloring.&lt;/p&gt;
&lt;figure id=&#34;win-hcm&#34; tabindex=&#34;-1&#34;&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Win HCM is a collection of user defined color themes that overwrite your definitions in CSS.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It&amp;rsquo;s not about design but readability.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some stuff will disappear in Win HCM, some won&amp;rsquo;t. Best advice is to use semantic HTML to keep things visible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can use transparent &lt;code&gt;outline&lt;/code&gt; to keep things visible like focus indicators and surface boundaries or use &lt;code&gt;current&lt;wbr /&gt;Color&lt;/code&gt; to maintain SVG &lt;code&gt;fill&lt;/code&gt; colors in Win HCM.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can use a special media query combined with special CSS color keywords to give elements the user defined colors.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://accessabilly.com/about/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Martin&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Mengele&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://accessabilly.com/accessibility-issues-concerning-windows-high-contrast-mode/&#34;&gt;Accessibility Issues concerning Windows High Contrast Mode&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;dark-themes&#34;&gt;Dark themes&lt;/h3&gt;
&lt;p&gt;If you do explicitly set colors, please also include a dark theme using a media query: &lt;code&gt;@media (prefers-color-scheme: dark)&lt;/code&gt;. For more info, read the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme&#34;&gt;&lt;code&gt;prefers-color-scheme&lt;/code&gt; docs on MDN&lt;/a&gt;. Dark themes are helpful for readers with migraines, photosensitivity (like me!), or dark environments.&lt;/p&gt;
&lt;p&gt;If you include a &lt;code&gt;theme-color&lt;/code&gt; directive in your document &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, then recent browsers will automatically switch their default stylesheets to dark-mode. Unfortunately, some older browsers (like Firefox-ESR) don&amp;rsquo;t support this directive, and WebKit&amp;rsquo;s default dark stylesheet &lt;a href=&#34;https://bugs.webkit.org/show_bug.cgi?id=209851&#34;&gt;has unreadable links&lt;/a&gt;. WebKit versions in the wild are often out of date, so a fixed stylesheet would need to be out for many years before I would consider using default dark stylesheets.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/wk_link.2389877422.jxl&#34;
type=&#34;image/jxl&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/wk_link.2784235963.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;171&#34; height=&#34;73&#34;
src=&#34;https://envs.net/~seirdy/p/wk_link.2784235963.png&#34; alt=&#34;dark blue link on dark gray background.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;WebKit’s default dark stylesheet uses dark-colored links that are difficult to read.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;CSS filters such as &lt;code&gt;invert&lt;/code&gt; are expensive to run, so use them sparingly. Simply inverting your page&amp;rsquo;s colors to provide a dark theme could slow it down or cause a user&amp;rsquo;s fans to spin.&lt;/p&gt;
&lt;p&gt;Darker backgrounds draw less power on devices with OLED screens; however, backgrounds should never be solid black. White text on a black background causes &lt;dfn id=&#34;halation&#34; tabindex=&#34;-1&#34;&gt;halation&lt;/dfn&gt;, especially among astigmatic readers. Halation comes from the word &amp;ldquo;halo&amp;rdquo;, and refers to a type of &amp;ldquo;glow&amp;rdquo; or ghosting around words. There has been some &lt;a href=&#34;https://www.laurenscharff.com/research/AHNCUR.html&#34;&gt;experimental color research&lt;/a&gt; and plenty of &lt;a href=&#34;https://jessicaotis.com/academia/never-use-white-text-on-a-black-background-astygmatism-and-conference-slides/&#34;&gt;anecdotal evidence from astigmatic users&lt;/a&gt; to support this.&lt;/p&gt;
&lt;figure&gt;
&lt;figcaption&gt;
&lt;p&gt;This image is an approximation of what halation looks like, cropped from &lt;a href=&#34;https://www.essentialaccessibility.com/blog/accessibility-for-people-with-astigmatism&#34;&gt;Essential Accessibility&lt;/a&gt;.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;picture&gt;&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/halation.231574643.avif&#34;
		type=&#34;image/avif&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/halation.2408567785.webp&#34;
		type=&#34;image/webp&#34; /&gt;
	&lt;source
		srcset=&#34;https://envs.net/~seirdy/~seirdy/p/halation.3866109654.png&#34;
		type=&#34;image/png&#34; /&gt;
	&lt;img
		width=&#34;354&#34; height=&#34;83&#34;
		src=&#34;https://envs.net/~seirdy/p/halation.3866109654.png&#34; alt=&#34;Fuzzy white text on black background reading “But it is not”.&#34;
		
		decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;
&lt;/figure&gt;

&lt;p&gt;&amp;ldquo;Just disable dark mode&amp;rdquo; is a poor response to users complaining about halation: it ignores the utility of dark themes described at the beginning of this section.&lt;/p&gt;
&lt;p&gt;If you can&amp;rsquo;t bear the thought of parting with your solid-black background, worry not: there exists a CSS media feature and client-hint for contrast preferences called &lt;code&gt;prefers-contrast&lt;/code&gt;. It takes the parameters &lt;code&gt;no-preference&lt;/code&gt;, &lt;code&gt;less&lt;/code&gt;, and &lt;code&gt;more&lt;/code&gt;. You can serve increased-contrast pages to those who request &lt;code&gt;more&lt;/code&gt;, and vice versa. Check section 11.3 of the W3C &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://drafts.csswg.org/mediaqueries-5/#prefers-contrast&#34;&gt;Media Queries Level 5&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; specification for more information.&lt;/p&gt;
&lt;p&gt;I personally like a foreground and background of &lt;code&gt;#E9E9E9&lt;/code&gt; and &lt;code&gt;#191919&lt;/code&gt;, respectively. These shades seem to be as far apart as possible without causing accessibility issues: &lt;code&gt;#191919&lt;/code&gt; is barely bright enough to create a soft &amp;ldquo;glow&amp;rdquo; capable of minimizing halos among slightly astigmatic users, but won&amp;rsquo;t ruin contrast on cheap displays. I also support a &lt;code&gt;prefers-contrast: less&lt;/code&gt; media query which lightens the background to &lt;code&gt;#333&lt;/code&gt;.&lt;sup id=&#34;fnref:25&#34;&gt;&lt;a href=&#34;#fn:25&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;25&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;use-the-advanced-perceptual-contrast-algorithm&#34;&gt;Use the Advanced Perceptual Contrast Algorithm&lt;/h3&gt;
&lt;p&gt;Color is a nuanced topic that deserves more attention than current guidelines give.&lt;/p&gt;
&lt;p&gt;When setting colors, especially for a dark background, I recommend checking your page&amp;rsquo;s contrast using Accessible Perceptual Contrast Algorithm (&lt;abbr title=&#34;Accessible Perceptual Contrast Algorithm&#34;&gt;APCA&lt;/abbr&gt;) values. You can do so in an &lt;a href=&#34;https://www.myndex.com/APCA/&#34;&gt;online APCA checker&lt;/a&gt; (requires JavaScript) or Chromium&amp;rsquo;s developer tools (you might have to enable them in a menu for experimental preferences). I recommend using the web app.&lt;/p&gt;
&lt;p&gt;The APCA takes several factors into account:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The human retina has few blue-sensitive cone cells, so blue appears &amp;ldquo;darker&amp;rdquo; than green and red. Yellow appears brightest.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Small, thin fonts are difficult to see and require greater contrast.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It&amp;rsquo;s possible to have too much contrast, especially for large/bold text (note that the APCA version built into Chromium does not yet take this into account).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that &lt;a href=&#34;https://yatil.net/blog/wcag-3-is-not-ready-yet&#34;&gt;the APCA isn&amp;rsquo;t fully mature&lt;/a&gt; as of early 2022. Until version 3.0 of the WCAG is ready, pages that are required to comply with the WCAG should also conform to the contrast ratios described in the WCAG 2.2&amp;rsquo;s success criteria 1.4.3 (Contrast: Minimum, level AA) or 1.4.6 (Contrast: Enhanced, level AAA). This site&amp;rsquo;s dark-mode stylesheet is an example of a palette that conforms to both the WCAG 2.2 AAA contrast requirements and APCA recommendations.&lt;/p&gt;
&lt;h3 id=&#34;what-contrast-algorithms-dont-cover-over-saturation&#34;&gt;What contrast algorithms don&amp;rsquo;t cover: over-saturation&lt;/h3&gt;
&lt;p&gt;Even if the APCA is much better than the WCAG&amp;rsquo;s current naive contrast algorithms, it still doesn&amp;rsquo;t account for all aspects of the relationship between perceptual contrast and color. &lt;a href=&#34;https://github.com/Myndex/SAPC-APCA/discussions/74&#34;&gt;Discussion no. 74 on the SAPC-APCA repository&lt;/a&gt; covers some shortcomings. For instance, the current APCA version does not account for &lt;a href=&#34;https://en.wikipedia.org/wiki/Helmholtz%E2%80%93Kohlrausch_effect&#34;&gt;the Helmholtz–Kohlrausch effect&lt;/a&gt;: highly-saturated colors appear &amp;ldquo;brighter&amp;rdquo; than de-saturated colors with the same brightness. Excessive perceptual brightness against dark backgrounds can trigger halation, eye-strain, and overstimulation.&lt;/p&gt;
&lt;p&gt;Yellow may have great contrast on dark backgrounds, but vivid yellow and red can cause problems among people who deal with overstimulation; this includes &lt;a href=&#34;https://www.experia.co.uk/blog/ultimate-guide-to-autism-friendly-colours/&#34;&gt;many on the autism spectrum&lt;/a&gt;. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://medium.com/@hello_93199&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Lē Silveus McNamara&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; wrote about the issue on the &lt;span&gt;&lt;span&gt;TPGi&lt;/span&gt;&lt;/span&gt; blog: &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.tpgi.com/beyond-wcag-losing-spoons-online/&#34;&gt;Beyond WCAG: Losing Spoons Online&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;.&lt;sup id=&#34;fnref:26&#34;&gt;&lt;a href=&#34;#fn:26&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;26&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;If you want to use significant amounts of &amp;ldquo;emergency colors&amp;rdquo; like yellow and red, de-saturate them so their color feels muted. This site&amp;rsquo;s dark theme uses very pale, washed-out yellow and violet for maximum contrast with minimal harshness.&lt;/p&gt;
&lt;p&gt;Accounting for halation, overstimulation, and high-contrast needs is hard to do if you prioritize minute aesthetics before inclusivity.&lt;/p&gt;
&lt;h3 id=&#34;contrast-under-different-conditions&#34;&gt;Contrast under different conditions&lt;/h3&gt;
&lt;p&gt;Color palettes need to be effective for different types of vision deficiencies (e.g. color blindnesses) and screens. Color blindness is a far more nuanced topic than &amp;ldquo;the inability to see some colors&amp;rdquo;. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;http://herpolhode.com/rob/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Rob&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Pike&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; describes his experience in &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://commandcenter.blogspot.com/2020/09/color-blindness-is-inaccurate-term.html&#34;&gt;Color blindness&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. Color blindness manifests in complex ways. Testing in grayscale is a great start, but it doesn&amp;rsquo;t account for all kinds of color vision deficiencies.&lt;/p&gt;
&lt;p&gt;Different screens and display-calibrations render color differently; what may look like a light-gray on a cheap monitor could look nearly black on a high-end OLED screen. Try to test on both high- and low-end displays, especially when designing a dark color scheme.&lt;sup id=&#34;fnref:27&#34;&gt;&lt;a href=&#34;#fn:27&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;27&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Color schemes should also look good to users who apply gamma adjustments. Most operating systems and desktop environments bundle a feature to reduce the screen color temperature at night, while some individuals may select a higher one in the morning.&lt;/p&gt;
&lt;h2 id=&#34;visible-interactive-semantics&#34;&gt;Visible interactive semantics&lt;/h2&gt;
&lt;figure&gt;
&lt;blockquote&gt;
	&lt;p&gt;Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element. (Level A)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/TR/WCAG22/&#34;&gt;WCAG 2.2&lt;/a&gt;&lt;/cite&gt;,
&lt;a href=&#34;https://www.w3.org/TR/WCAG22/#distinguishable&#34;&gt;section 1.4.1&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A basic WCAG Level A requirement is for information to not be conveyed solely through color. Both the presence and type of interactivity need to be visually communicated by other means. Links should not look like buttons, and vice-versa.&lt;/p&gt;
&lt;h3 id=&#34;in-defense-of-link-underlines&#34;&gt;In defense of link underlines&lt;/h3&gt;
&lt;p&gt;Some typographers insist that &lt;a href=&#34;https://practicaltypography.com/underlining.html&#34;&gt;underlined on-screen text is obsolete&lt;/a&gt;,&lt;sup id=&#34;fnref:28&#34;&gt;&lt;a href=&#34;#fn:28&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;28&lt;/a&gt;&lt;/sup&gt; and that hyperlinks are no exception. I disagree.&lt;/p&gt;
&lt;p&gt;Readers already expect underlined text to signify a hyperlink. Don&amp;rsquo;t break fundamental affordances for aesthetics. Underlines are also necessary to distinguish the beginnings and ends of multiple consecutive links, especially among color-blind users.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/underlines_dark.2238017752.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/underlines_dark.645867768.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/underlines.448520703.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/underlines.2239050794.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;420&#34; height=&#34;162&#34;
src=&#34;https://envs.net/~seirdy/p/underlines.2239050794.png&#34; alt=&#34;Multiple multi-word hyperlinks with and without underlines separating them.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;It&amp;rsquo;s impossible to discern the number of links in a sequence without some sort of separator. Whitespace alone isn&amp;rsquo;t sufficient.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;Moreover, several parts of &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/TR/coga-usable/&#34;&gt;Making Content Usable for People with Cognitive and Learning Disabilities&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; recommend underlining links.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Some users have trouble when controls have a different look, color, or shape than they have used before. For example, when links do not have underlines and blue or purple text some users will not know there is a link (even if this appears with focus).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;Making Content Usable for People with Cognitive and Learning Disabilities&lt;/cite&gt;, section 4.2.5.3:
&lt;a href=&#34;https://www.w3.org/TR/coga-usable/#how-it-helps-3&#34;&gt;Clearly Identify Controls and Their Use: How it Helps&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This stance is not absolute. Users are familiar with very common design patterns, such as navigation bars and search results. Underlines are still preferable, but I find their absence less concerning in these cases.&lt;/p&gt;
&lt;h3 id=&#34;buttons-versus-links&#34;&gt;Buttons versus links&lt;/h3&gt;
&lt;p&gt;Buttons are another type of interactive element. Users are accustomed to recognizing buttons by their visually distinct interactive region. While hyperlinks are only signified by color and a text underline, buttons are signified by a background-color change and/or a visible border. Do not conflate the two!&lt;/p&gt;
&lt;p&gt;The purpose of a hyperlink is to navigate to a different location. If a button exists to do the same thing, it shouldn&amp;rsquo;t be a button; it should have both hyperlink semantics and presentation instead. Otherwise, the consequences of element activation are unclear.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Use a clear and recognizable design for controls. Make it clear what elements are controls and how to use them.&lt;/p&gt;
&lt;p&gt;This includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using a common style on controls (for example, links being underlined).&lt;/li&gt;
&lt;li&gt;Using common design patterns on links and controls (for example, clicking on a link takes you to the page).&lt;/li&gt;
&lt;li&gt;Making the borders of controls clear. Links in text do not need borders if identified properly (for example, a help icon has a border).&lt;/li&gt;
&lt;li&gt;Making controls large enough so that users can click on it and not the item next to it.&lt;/li&gt;
&lt;li&gt;Ensuring items that are not clickable do not look like links or controls.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When this is not possible, provide instructions that explain how to use the control.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;Making Content Usable for People with Cognitive and Learning Disabilities&lt;/cite&gt;, section 4.2.5.2:
&lt;a href=&#34;https://www.w3.org/TR/coga-usable/#what-to-do-3&#34;&gt;Clearly Identify Controls and Their Use: What to Do&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;One key difference between buttons and links is the cursor appearance. Buttons should not turn the cursor into a &amp;ldquo;hand&amp;rdquo; or &amp;ldquo;pointer&amp;rdquo; icon. The article &lt;span
	class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://hidde.blog/some-pointers-on-default-cursors/&#34;&gt;Some pointers on default cursors&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://hidde.blog/about-me/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;Hidde de Vries&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; covers both sides of the issue. Personally, I think it&amp;rsquo;s best to respect the convention of the browser and OS rather than break it.&lt;/p&gt;
&lt;p&gt;Read more about the differences between buttons and links in &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://yatil.net/blog/buttons-vs-links&#34;&gt;Buttons vs. Links&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://yatil.net/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Eric&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Eggbert&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id=&#34;visible-non-interactive-semantics&#34;&gt;Visible non-interactive semantics&lt;/h3&gt;
&lt;p&gt;In addition to &lt;a href=&#34;#non-interactive-space&#34;&gt;offering ample non-interactive space&lt;/a&gt;, ensure that non-interactive and interactive regions are visually distinct. Avoid making interactive elements with many children.&lt;/p&gt;
&lt;p&gt;GitHub&amp;rsquo;s mobile website is a serious offender; see &lt;a href=&#34;#gh-interactive&#34;&gt;this screenshot of the GitHub bug tracker&lt;/a&gt; for an example.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The background region of the visible issue is interactive, and so are its contents.&lt;/li&gt;
&lt;li&gt;The header of the issues list has a non-interactive background that looks the same as the aforementioned interactive background.&lt;/li&gt;
&lt;li&gt;Visual appearance does not convey the difference between a button and a hyperlink: The &amp;ldquo;enhancement&amp;rdquo; link looks like a button&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;enhancement&amp;rdquo; link points to a unique location, yet it loses its interactivity on narrow viewports with no visual change; tapping it navigates to a different location depending on viewport width.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&#34;gh-interactive&#34; tabindex=&#34;-1&#34;&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/gh_interactive_dark.887830380.jxl&#34;
type=&#34;image/jxl&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/gh_interactive_dark.4236121760.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/gh_interactive_dark.1474084872.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/gh_interactive.3336307262.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/gh_interactive.3132897548.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;444&#34; height=&#34;318&#34;
src=&#34;https://envs.net/~seirdy/p/gh_interactive.3132897548.png&#34; alt=&#34;Screenshot of GitHub issues on mobile with non-underlined links and links that look like buttons.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
Screenshot of the &lt;a href=&#34;https://github.com/nihui/waifu2x-ncnn-vulkan/issues&#34;&gt;GitHub issues for waifu2x-ncnn-vulkan&lt;/a&gt;.
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Someone using the GitHub issues interface for the first time will struggle to identify interactive regions and discern whether they trigger navigations or different actions.&lt;/p&gt;
&lt;h3 id=&#34;against-focusable-containers&#34;&gt;Against focusable containers&lt;/h3&gt;
&lt;p&gt;Screen readers like iOS VoiceOver&lt;sup id=&#34;fnref:29&#34;&gt;&lt;a href=&#34;#fn:29&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;29&lt;/a&gt;&lt;/sup&gt; fail to follow in-page links whose targets are not focusable. Designers often work around this by annotating link targets with the &lt;code&gt;tabindex=&amp;quot;-1&amp;quot;&lt;/code&gt; HTML attribute. This is a good idea when a link target is a heading or piece of &lt;a href=&#34;https://html.spec.whatwg.org/dev/dom.html#phrasing-content&#34;&gt;phrasing content&lt;/a&gt;. Unfortunately, making large containers focusable ruins keyboard-navigability.&lt;/p&gt;
&lt;p&gt;Normally, if you select some text in a page and press &lt;kbd&gt;Tab&lt;/kbd&gt;, the tab-focusable element &lt;em&gt;after&lt;/em&gt; the selected text will receive focus. However, if the selectable text is inside a focusable container&amp;mdash;even a container with a negative &lt;code&gt;tabindex&lt;/code&gt;&amp;mdash;pressing &lt;kbd&gt;Tab&lt;/kbd&gt; will move focus to the &lt;em&gt;start&lt;/em&gt; of the container. If you&amp;rsquo;re reading this on a desktop browser, you can experience this first-hand: select some text in this paragraph and press &lt;kbd&gt;Tab&lt;/kbd&gt;. Then, do the same in &lt;a href=&#34;https://web.archive.org/web/20220808163715/https://www.smashingmagazine.com/2022/06/voice-control-usability-considerations-partially-visually-hidden-link-names/&#34;&gt;this snapshot of an excellent &lt;em&gt;Smashing Magazine&lt;/em&gt; article&lt;/a&gt;.&lt;sup id=&#34;fnref:30&#34;&gt;&lt;a href=&#34;#fn:30&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;30&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;figure id=&#34;focus-container&#34; tabindex=&#34;-1&#34;&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus-container_dark.1686289108.webp&#34;
type=&#34;image/webp&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus-container_dark.1972821252.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus-container.2214455554.jxl&#34;
type=&#34;image/jxl&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus-container.535693757.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus-container.451731332.webp&#34;
type=&#34;image/webp&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus-container.327081666.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;631&#34; height=&#34;510&#34;
src=&#34;https://envs.net/~seirdy/p/focus-container.327081666.png&#34; alt=&#34;Two screenshots of an article byline above a title. First, the title has selected text; then, the byline is focused.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Two screenshots of &lt;a href=&#34;https://web.archive.org/web/20220808163715/https://www.smashingmagazine.com/2022/06/voice-control-usability-considerations-partially-visually-hidden-link-names/&#34;&gt;the aforementioned &lt;em&gt;Smashing Magazine&lt;/em&gt; article&lt;/a&gt; after I selected the title text, before and after pressing &lt;kbd&gt;Tab&lt;/kbd&gt;. The focus moves &lt;em&gt;backwards&lt;/em&gt; to the start of the container because the container is focusable. The focus should have moved to an element after the selected text.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;This behavior is particularly frustrating on long pages. Imagine if pressing &lt;kbd&gt;Tab&lt;/kbd&gt; took you to the start of this article!&lt;/p&gt;
&lt;h2 id=&#34;image-optimization&#34;&gt;Image optimization&lt;/h2&gt;
&lt;p&gt;Some image optimization tools I use:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://pngquant.org&#34;&gt;&lt;code&gt;pngquant&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;lossy PNG compression. Can reduce the size of the color palette.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.lcdf.org/gifsicle/&#34;&gt;&lt;code&gt;gifsicle&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Optimizes GIF images, static or animated. Supports many dithering options and advanced optimization options for animations.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/makew0rld/didder&#34;&gt;&lt;code&gt;didder&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Offers more advanced dithering options than gifsicle and pngquant.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/shssoichiro/oxipng&#34;&gt;&lt;code&gt;oxipng&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Lossless PNG compression. It&amp;rsquo;s like a parallelized version of &lt;a href=&#34;https://optipng.sourceforge.net/&#34;&gt;OptiPNG&lt;/a&gt; that also supports an implementation of &lt;a href=&#34;https://github.com/google/zopfli/blob/831773bc28e318b91a3255fa12c9fcde1606058b/README.zopflipng&#34;&gt;ZopfliPNG&lt;/a&gt; compression&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/tjko/jpegoptim&#34;&gt;&lt;code&gt;jpegoptim&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Lossless or lossy JPEG compression. Note that JPEG is an inherently lossy format; the lossless features of &lt;code&gt;jpegoptim&lt;/code&gt; only shrink the size of existing JPEG files by removing unnecessary metadata.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://developers.google.com/speed/webp/docs/cwebp&#34;&gt;&lt;code&gt;cwebp&lt;/code&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The reference WebP encoder; has dedicated lossless and lossy modes. Lossy WebP compression isn&amp;rsquo;t always better than JPEG, but lossless WebP consistently beats PNG.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;avifenc&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The reference AVIF encoder, included in &lt;a href=&#34;https://github.com/AOMediaCodec/libavif&#34;&gt;libavif&lt;/a&gt;.&lt;sup id=&#34;fnref:31&#34;&gt;&lt;a href=&#34;#fn:31&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;31&lt;/a&gt;&lt;/sup&gt; AVIF lossless compression is typically useless, but its lossy compression is pretty unique in that it leans towards detail removal rather than introducing compression artifacts. Note that AVIF is not supported by Safari or most WebKit-based browsers. It also seems unsupported in Microsoft Edge.&lt;sup id=&#34;fnref:32&#34;&gt;&lt;a href=&#34;#fn:32&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;32&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;I put together &lt;a href=&#34;https://git.sr.ht/~seirdy/dotfiles/tree/3b722a843f3945a1bdf98672e09786f0213ec6f6/Executables/shell-scripts/bin/optimize-image&#34;&gt;a quick script&lt;/a&gt; to losslessly optimize images using these programs. For lossy compression, I typically use &lt;a href=&#34;https://www.gnu.org/software/parallel/&#34;&gt;GNU Parallel&lt;/a&gt; to mass-generate images using different options before selecting the smallest image at the minimum acceptable quality. Users who&amp;rsquo;d rather avoid the command line while performing lossy compression can instead check out &lt;a href=&#34;https://squoosh.app/&#34;&gt;Squoosh&lt;/a&gt;, a JavaScript app that bundles Web­Assembly-compiled encoders; I&amp;rsquo;ve heard good things about it.&lt;/p&gt;
&lt;p&gt;You also might want to use the HTML &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element, using JPEG/PNG as a fallback for more efficient formats such as WebP or AVIF, but only if the size savings (or quality improvements at a similar size) are significant. More info is in the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture&#34;&gt;MDN &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Most of my images will probably be screenshots that start as PNGs. My typical flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Re-size and crop the PNG. Convert to grayscale if color isn&amp;rsquo;t important.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lossy compression with &lt;code&gt;pngquant&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Losslessly optimize the result with &lt;code&gt;oxipng&lt;/code&gt; and its Zopfli backend (slow)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Also create a lossless WebP from the lossy PNG and a lossy WebP from the source image, using &lt;code&gt;cwebp&lt;/code&gt;. Pick the smaller of the two.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Include the resulting WebP in the page, with a fallback to the PNG using a &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a lossy AVIF image from the cropped full-color PNG, and include it in the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element if it&amp;rsquo;s smaller than the WebP. If color isn&amp;rsquo;t important, use the YUV400 color space.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the image is too light, repeat for a dark version of the image to display in response to a &lt;code&gt;prefers-color-scheme: dark&lt;/code&gt; media query.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In general, avoid loading images just for decoration. Only use an image if it has a clear purpose that significantly adds to the content in a way that text can&amp;rsquo;t replace, and provide alt-text as a fallback. Any level of detail that isn&amp;rsquo;t necessary for getting the point across should be removed by lossy compression and cropping.&lt;/p&gt;
&lt;p&gt;If you want to include a profile photo (e.g., if your website is part of the IndieWeb and uses an &lt;a href=&#34;https://microformats.org/wiki/h-card&#34;&gt;h-card&lt;/a&gt;), I recommend re-using one of your favicons. Doing so should be harmless since most browsers will fetch and cache favicons anyway.&lt;/p&gt;
&lt;p&gt;If you really want to take PNG optimization to the next level, try &lt;a href=&#34;https://github.com/fhanau/Efficient-Compression-Tool&#34;&gt;Efficient Compression Tool&lt;/a&gt;.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;png-pipeline&#34;&gt;
&lt;figcaption id=&#34;png-pipeline-caption&#34;&gt;
	&lt;span id=&#34;png-pipeline&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 17&lt;/strong&gt; (&lt;span&gt;shell&lt;/span&gt;)&lt;/span&gt;:
this is a sample command to compress a PNG image using ImageMagick, &lt;code&gt;pngquant&lt;/code&gt;, and &lt;code&gt;oxipng&lt;/code&gt;. It shrinks the image, turns it grayscale, reduces the color palette, and then applies lossless Zopfli compression.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;convert ORIGINAL_FILE \
  -resize 75% -colorspace gray -format png - \
  | pngquant -s 1 12 - \
  | oxipng -o max -Z --fix - --out OUTPUT_FILE
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;breaking-conventional-wisdom&#34;&gt;Breaking conventional wisdom&lt;/h3&gt;
&lt;p&gt;Some conventional wisdom for image compression doesn&amp;rsquo;t hold up when compressing this aggressively; for instance, I&amp;rsquo;ve found that extremely aggressive dithering and PNG compression of small black-and-white images consistently surpasses JPEG compression.&lt;/p&gt;
&lt;p&gt;Most resources on image optimization recommend progressive rendering. I don&amp;rsquo;t recommend progressive rendering for below-the-fold images; if you optimize an image to just a few kilobytes, it should fully load in time. It&amp;rsquo;s not worth the overhead for resources of less than 20 kb.&lt;/p&gt;
&lt;p&gt;These resources also encourage authors to include different image variants for different viewport sizes, screen resolutions, and pixel densities. They often skip the caveats:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Using different image files for different viewport sizes can cause the page to request more images as users re-size their window.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sending requests dependent on viewport and display characteristics is a fingerprinting vector, allowing servers to identify users by these properties.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rather than create separate lanes for different users, I prefer making the defaults as inclusive as possible. A single image should look good under a variety of downscaling algorithms. It should be as small as it can be without losing essential information.&lt;/p&gt;
&lt;p&gt;It might seem odd to create a lossless WebP from a lossy PNG, but I&amp;rsquo;ve found that it&amp;rsquo;s often the best way to get the smallest possible image at the minimum acceptable quality for screenshots containing solid backgrounds.&lt;/p&gt;
&lt;h3 id=&#34;enforce-image-compression&#34;&gt;Enforce image compression&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/wicg/document-policy/blob/main/document-policy-explainer.md&#34;&gt;The &amp;ldquo;Document Policy&amp;rdquo; HTTP header&lt;/a&gt; has experimental directives &lt;code&gt;lossless-images-max-bpp&lt;/code&gt; and &lt;code&gt;lossy-images-max-bpp&lt;/code&gt;. In this context, &amp;ldquo;bpp&amp;rdquo; refers to &amp;ldquo;bytes per pixel&amp;rdquo;; a 256-by-256 pixel image that&amp;rsquo;s 6.6 kilobytes large would have a &amp;ldquo;bpp&amp;rdquo; of 0.1. If it&amp;rsquo;s a lossy image, then sending &lt;code&gt;lossy-images-max-bpp=0.1&lt;/code&gt; would forbid the image from loading if it&amp;rsquo;s over 6.6 kilobytes in size.&lt;/p&gt;
&lt;p&gt;Currently, these directives are disabled-by-default in Chromium; you can enable them by navigating to &lt;code&gt;chrome://flags&lt;/code&gt; and toggling &amp;ldquo;Experimental Web platform features&amp;rdquo;. &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/notes/2022/08/12/document-policy-and-image-compression/&#34;&gt;I don&amp;rsquo;t think these directives are perfect&lt;/a&gt;, but they are quite useful.&lt;/p&gt;
&lt;h3 id=&#34;dark-image-variants&#34;&gt;Dark image variants&lt;/h3&gt;
&lt;p&gt;Bright images on an otherwise dark page distract readers, especially readers like me with ADHD. The human iris adjusts to average amounts of light; an object far brighter than its surroundings causes eye strain even among readers with healthy vision.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element allows selection of sources based on any CSS media query. When images have light backgrounds, I like to include dark variants to complement a dark stylesheet using an HTML &lt;code&gt;media&lt;/code&gt; attribute: it selects a dark variant when the user has selected dark mode and is using a &lt;code&gt;screen&lt;/code&gt; media type. Requiring the &lt;code&gt;screen&lt;/code&gt; media type prevents selection of dark variants when printing. Printer paper is almost always white, so dark images could waste ink. Ink waste is a sensitive issue among many students: school printers sometimes charge students who exceed a given ink quota. Ask me how I know!&lt;/p&gt;
&lt;p&gt;Light and dark variants of legacy formats (PNG, JPG, GIF), WebP, and AVIF can cause some of my &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; imagesets to have up to six image variants. I could fully automate the process using my static site generator (Hugo) if I wanted to. Since I do want to inspect each image and compress to the minimum acceptable quality, I settled for partial automation using shell scripts and &lt;a href=&#34;https://git.sr.ht/~seirdy/seirdy.one/tree/master/layouts/shortcodes/picture.html&#34;&gt;a Hugo shortcode&lt;/a&gt;.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-18-caption&#34;&gt;
	&lt;span id=&#34;code-18&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 18&lt;/strong&gt; (&lt;span&gt;HTML&lt;/span&gt;)&lt;/span&gt;:
A minimal example of a &lt;code&gt;picture&lt;/code&gt; containing a dark variant and two image formats.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;picture&amp;gt;
&amp;lt;source type=&amp;quot;image/webp&amp;quot; srcset=&amp;quot;/p/light.webp&amp;quot;&amp;gt;
&amp;lt;source type=&amp;quot;image/webp&amp;quot; srcset=&amp;quot;/p/dark.webp&amp;quot;
  media=&amp;quot;screen and (prefers-color-scheme: dark)&amp;quot;&amp;gt;
&amp;lt;source type=&amp;quot;image/png&amp;quot; srcset=&amp;quot;/p/dark.png&amp;quot;
  media=&amp;quot;screen and (prefers-color-scheme: dark)&amp;quot;&amp;gt;
&amp;lt;img src=&amp;quot;/p/light.png&amp;quot; alt=&amp;quot;ALTERNATIVE_TEXT.&amp;quot;
  width=&amp;quot;WIDTH&amp;quot; height=&amp;quot;HEIGHT&amp;quot;&amp;gt;
&amp;lt;picture&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;svg-images&#34;&gt;SVG images&lt;/h3&gt;
&lt;p&gt;I only recommend using SVG in images; avoid using them in embeds, objects, or directly in the body. Remember that users may save images, and open them in a non-browser image viewer with reduced SVG compatibility. To maintain maximum compatibility, stick the subset of the &lt;a href=&#34;https://www.w3.org/TR/SVG/conform.html#secure-static-mode&#34;&gt;secure static processing mode&lt;/a&gt; of &lt;a href=&#34;https://www.w3.org/TR/SVG11/feature#SVG-static&#34;&gt;SVG Static&lt;/a&gt;. Specifically, the subset that appears in the &lt;a href=&#34;https://datatracker.ietf.org/doc/draft-svg-tiny-ps-abrotman/&#34;&gt;SVG Tiny Portable&lt;wbr /&gt;/Secure (&lt;abbr title=&#34;Portable/Secure&#34;&gt;PS&lt;/abbr&gt;) spec&lt;/a&gt;. SVG Tiny PS is a subset of &lt;a href=&#34;https://www.w3.org/TR/SVGTiny12/intro.html&#34;&gt;SVG Tiny 1.2&lt;/a&gt;, which is a supported export format in most vector drawing programs. Ignore the elements specifically required for SVG Tiny PS; your image can be a standard SVG that only utilizes a tiny subset of the full SVG spec.&lt;/p&gt;
&lt;p&gt;This advice might seem daunting, but it’s usually easy to use existing tools to generate an SVG Tiny file and manually edit it to support the SVG secure static mode. SVGs that conform to this subset should be compatible with Qt5&amp;rsquo;s SVG implementation, librsvg (used by Wikipedia and GNOME), and most operating systems&amp;rsquo; icon renderers. Moreover, tools like &lt;a href=&#34;https://github.com/RazrFalcon/resvg/tree/master/crates/usvg&#34;&gt;usvg&lt;/a&gt; can simplify complex SVGs to &lt;a href=&#34;https://github.com/RazrFalcon/resvg/blob/ad139d38e3db11fd6313e0409bf86f92eb52b383/crates/usvg/docs/spec.adoc&#34;&gt;a tiny subset of the SVG spec&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Two tools that can optimize the size of an SVG file are &lt;a href=&#34;https://github.com/svg/svgo&#34;&gt;SVGO&lt;/a&gt; and the now-discontinued &lt;a href=&#34;https://github.com/RazrFalcon/svgcleaner&#34;&gt;svgcleaner&lt;/a&gt;. Too much lossy SVG compression can sometimes &lt;em&gt;reduce&lt;/em&gt; the effectiveness of gzip and Brotli compression. Compress in moderation.&lt;/p&gt;
&lt;h2 id=&#34;layout&#34;&gt;Layout&lt;/h2&gt;
&lt;p&gt;Page layout should be simple, predictable, consistent, familiar, and static. Avoid anything too unusual, since novelty could introduce a learning curve.&lt;/p&gt;
&lt;h3 id=&#34;accessible-skimming&#34;&gt;Accessible skimming&lt;/h3&gt;
&lt;p&gt;Keep the source order, DOM order, and visual order identical to ensure consistent behavior when navigating with the mouse, keyboard, assistive-technology, et al. Doing so should also result in a logical &lt;kbd&gt;Tab&lt;/kbd&gt; order.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.w3.org/TR/WCAG22/#navigable&#34;&gt;Guideline 2.4 Navigable&lt;/a&gt; of the WCAG lists multiple criteria related to identifying and skipping sections of your pages, and for good reason:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Users of &lt;a href=&#34;https://en.wikipedia.org/wiki/Switch_access&#34;&gt;switch access controls&lt;/a&gt; find it slow and frustrating to navigate long lists of focusable items.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Screen readers make it difficult to consume poorly-organized content non-linearly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clients that don&amp;rsquo;t support CSS can&amp;rsquo;t prioritize content using a supplied stylesheet.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list goes on: nearly every reader reliant upon assistive technologies (&lt;abbr title=&#34;assistive technology&#34;&gt;AT&lt;/abbr&gt;) struggles to skim through poorly-organized pages.&lt;/p&gt;
&lt;p&gt;Related items need to be semantically grouped together. Group navigation links together in &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; elements; sections under headings and landmarks; lists under &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;dl&amp;gt;&lt;/code&gt;; etc. to give assistive technologies the means to skip over multiple items at once.&lt;/p&gt;
&lt;p&gt;The first or second heading in the DOM, and the highest heading level, should be the page title marking the start of your main content (i.e. it should come after the site title, site navigation links, etc). Use elements like &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; to provide landmarks. If multiple navigation elements exist, give your main navigation element an &lt;code&gt;aria-label&lt;/code&gt; or a heading.&lt;/p&gt;
&lt;p&gt;Remember that not all landmarks are announced by screen readers; for instance, many screen readers don&amp;rsquo;t announce the ending of a &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; element in an article. An &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; element is a good way to force the ending of a landmark to be visible: it introduces a thematic break between sections that is visible to assistive technologies and user-agents that don&amp;rsquo;t support CSS.&lt;/p&gt;
&lt;p&gt;Consider adding a &amp;ldquo;skip link&amp;rdquo; if some pages require many &lt;kbd&gt;Tab&lt;/kbd&gt; keystrokes to reach the main content.&lt;sup id=&#34;fnref:33&#34;&gt;&lt;a href=&#34;#fn:33&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;33&lt;/a&gt;&lt;/sup&gt; Visually-impaired users generally prefer navigating by headings or landmarks, but screen reader beginners and motor-impaired users still benefit from a skip link. Skip links are especially helpful when pure heading- and landmark-based navigation isn&amp;rsquo;t optimal.&lt;/p&gt;
&lt;p&gt;If your skip link toggles visibility states when focused, ensure that it doesn&amp;rsquo;t move any existing content; see &lt;a href=&#34;#layout-shifts&#34;&gt;the &amp;ldquo;Layout shifts&amp;rdquo; section&lt;/a&gt; for more details. If it appears over existing content, it needs to have a solid background; if you set the background color, set a foreground color too as described in &lt;a href=&#34;#about-custom-colors&#34;&gt;the &amp;ldquo;About custom colors&amp;rdquo; section&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;friendly-navigation&#34;&gt;Friendly navigation&lt;/h3&gt;
&lt;p&gt;Users of &lt;abbr title=&#34;assistive technologies&#34;&gt;ATs&lt;/abbr&gt; such as screen readers primarily navigate through landmarks, headings, and paragraphs. Sometimes they also navigate between links. Headings and link names need to be unique and descriptive enough to serve as navigational aids; paragraphs shouldn&amp;rsquo;t be too long.&lt;/p&gt;
&lt;p&gt;Try using a tool to view a list of all your link names. Just about every screen reader and some browser extensions should offer this functionality. Minimize links with ambiguous names, and ensure that identical link names have identical destinations.&lt;/p&gt;
&lt;p&gt;Think twice before placing important content immediately after skippable content such as nested landmarks, long code snippets, figures, and large lists. AT users who wish to skip content may jump directly to the next heading, glossing over anything between the skippable content and subsequent heading; this is especially common on mobile devices.&lt;sup id=&#34;fnref:34&#34;&gt;&lt;a href=&#34;#fn:34&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;34&lt;/a&gt;&lt;/sup&gt; When it makes sense to do so, place skippable content in its own sections and/or at the end of its parent section.&lt;/p&gt;
&lt;h3 id=&#34;single-column-layout&#34;&gt;Single-column layout&lt;/h3&gt;
&lt;p&gt;The remainder of the &amp;ldquo;Layout&amp;rdquo; section is possibly the most subjective part of this article, and the part with the most exceptions. Consider it more of a weak suggestion than hard advice. Use your own judgement.&lt;/p&gt;
&lt;p&gt;A simple layout looks good at a variety of window sizes, rendering responsive layout changes unnecessary. Textual websites really don&amp;rsquo;t need more than a single column; readers should be able to scan a page top-to-bottom, side-to-side exactly once to read all its content.&lt;/p&gt;
&lt;p&gt;Verify this using the horizontal-line test: mentally draw a horizontal line across your page, and make sure it doesn&amp;rsquo;t intersect more than one landmark. Ideally it shouldn&amp;rsquo;t intersect multiple different &lt;a href=&#34;https://html.spec.whatwg.org/dev/grouping-content.html&#34;&gt;grouping elements&lt;/a&gt; either. The &amp;ldquo;source order viewer&amp;rdquo; in Chromium&amp;rsquo;s DevTools can assist with this process.&lt;/p&gt;
&lt;p&gt;Keeping a single-column layout that doesn&amp;rsquo;t require responsive layout changes ensures smooth window re-sizing. Doing so while keeping an identical source, DOM, and visual order ensures layout consistency: spatial references such as &amp;ldquo;the paragraph above this heading&amp;rdquo; or &amp;ldquo;the bottom image of a section&amp;rdquo; will be unambiguous to screen reader, phone, and desktop users. It also ensures that selection behavior and caret movements during &lt;a href=&#34;https://en.wikipedia.org/wiki/Caret_navigation&#34;&gt;caret navigation&lt;/a&gt; remain predictable. Achieving this type of layout entails using the WCAG 2.2 techniques &lt;cite&gt;&lt;a href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/css/C27.html&#34;&gt;C27: Making the DOM order match the visual order&lt;/a&gt;&lt;/cite&gt; as well as &lt;cite&gt;&lt;a href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/css/C6&#34;&gt;C6: Positioning content based on structural markup&lt;/a&gt;&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;Nontrivial use of width-selectors, in CSS queries or imagesets, is actually a powerful vector for &lt;a href=&#34;https://web.archive.org/web/20221022104555/https://matt.traudt.xyz/posts/2016-09-04-how-css-alone-can-help-track-you/&#34;&gt;JS-free fingerprinting&lt;/a&gt;. This is one of the reasons why I didn&amp;rsquo;t recommend resolution- or dimension-aware imagesets in the &lt;a href=&#34;#image-optimization&#34;&gt;image optimization section&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Exceptions exist: one or two very simple responsive changes won&amp;rsquo;t hurt. The main anti-patterns are adjusting the relative order of elements, layout shifts dramatic enough to cause confusion, and making requests based on media queries that reveal fingerprintable information.&lt;/p&gt;
&lt;h3 id=&#34;sidebar-pitfalls&#34;&gt;Sidebar pitfalls&lt;/h3&gt;
&lt;p&gt;Sidebars are probably unnecessary, and can be quite annoying to readers who re-size windows frequently. This is especially true for tiling window manager users like me: we frequently shrink windows to a fraction of their original size. When this happens to a website with a sidebar, one of two things happens:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The site&amp;rsquo;s responsive design kicks in: the sidebar vanishes and its elements move elsewhere. This can be quite CPU-heavy, as the browser has to both re-wrap the text and handle a complex layout change. Frequent window re-sizers will experience lag and battery loss, and might need a moment to figure out where everything went.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The site doesn&amp;rsquo;t use responsive design. The navbar and main content are now squeezed together. Readers will probably close the page.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Neither situation looks great.&lt;/p&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://w3c.github.io/low-vision-a11y-tf/requirements#maintain-point-of-regard&#34;&gt;Low Vision User Accessibility Requirements&lt;/a&gt;&lt;/cite&gt; by the &lt;abbr title=&#34;Web Accessibility Initiative&#34;&gt;WAI&lt;/abbr&gt;&lt;/span&gt; is a work-in-progress document that describes issues caused by significant responsive changes. It encourages designers to &amp;ldquo;maintain point of regard&amp;rdquo; during responsive changes (the &amp;ldquo;point of regard&amp;rdquo; is the place a reader is looking at). Unfortunately, it&amp;rsquo;s not always possible to &amp;ldquo;guess&amp;rdquo; whether the point of regard is the main content or a sidebar.&lt;/p&gt;
&lt;h3 id=&#34;sidebar-alternatives&#34;&gt;Sidebar alternatives&lt;/h3&gt;
&lt;p&gt;Common items in sidebars include tag clouds, an author bio, and an index of entries; these aren&amp;rsquo;t useful while reading an article. Consider putting them in the article footer or&amp;mdash;even better&amp;mdash;dedicated pages. This does mean that readers will have to navigate to a different page to see that content, but they probably prefer things that way; almost nobody who clicked on &amp;ldquo;An opinionated list of best practices for textual websites&amp;rdquo; did so because they wanted to read my bio.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t boost engagement by giving readers information they didn&amp;rsquo;t ask for; earn engagement with good content, and let readers navigate to your other pages &lt;em&gt;after&lt;/em&gt; they&amp;rsquo;ve decided they want to read more.&lt;/p&gt;
&lt;h3 id=&#34;line-length&#34;&gt;Line length&lt;/h3&gt;
&lt;p&gt;As words-per-line decrease (by increasing zoom or narrowing the viewport), line lengths grow more varied. Justifying text will cause uncomfortable amounts of whitespace. In fact, &lt;q cite=&#34;https://www.w3.org/TR/WCAG22/#visual-presentation&#34;&gt;Text is not justified&lt;/q&gt; is explicitly mentioned in the WCAG Success Criterion 1.4.8.&lt;/p&gt;
&lt;p&gt;The WCAG recommends a max line length of 80 characters (40 characters for &lt;abbr title=&#34;Chinese, Japanese, and Korean&#34;&gt;CJK&lt;/abbr&gt; languages) as &lt;a href=&#34;https://www.w3.org/TR/WCAG22/#visual-presentation&#34;&gt;a AAA success criterion (SC 1.4.8)&lt;/a&gt;. However, studies seem to have mixed results; some people find it easier to read lines around 90 characters long, while others struggle beyond the 50-character mark.&lt;/p&gt;
&lt;p&gt;I think the WCAG over-simplified a complex issue to make this success criterion easier to understand. The guideline in its current form encourages wrapping lines at uneven lengths, since proportional text can take up varying amounts of space for a given character count. It would be better to specify an average character length, allowing lines with narrow characters (e.g. &amp;ldquo;I&amp;rdquo;, &amp;ldquo;l&amp;rdquo;) to exceed it. Then again, the AAA level was never intended to be a blanket requirement.&lt;/p&gt;
&lt;p&gt;Some of my links display long link-text; short line lengths can break these link texts too much, which can slightly hurt readability. Of course, narrow viewports will obviously make short line lengths non-negotiable. I decided to give article bodies a width of &lt;code&gt;36em&lt;/code&gt;, which corresponds to just over 80 characters on most default stylesheets. I opted to use &lt;code&gt;em&lt;/code&gt; instead of &lt;code&gt;ch&lt;/code&gt; for consistency and for better compatibility with some uncommon browsers (NetSurf, Dillo, old versions of mainstream browsers, and others).&lt;/p&gt;
&lt;p&gt;I also ensured that my site supports CSS overrides, window-resizing, zoom levels past 200%, and most &amp;ldquo;reading mode&amp;rdquo; implementations. This should help accommodate a wide range of line-length preferences while still looking accessible enough by default.&lt;/p&gt;
&lt;p&gt;When setting max line lengths, use a CSS media query to ensure that printed versions of a page use the full page width. This should save some paper.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-19-caption&#34;&gt;
	&lt;span id=&#34;code-19&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 19&lt;/strong&gt; (&lt;span&gt;CSS&lt;/span&gt;)&lt;/span&gt;:
I opted to wrap all max-width rules in a media query to ensure that they only get called for the &lt;code&gt;screen&lt;/code&gt; media type:
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;@media screen {
  html {
    max-width: 45em;
    padding: 0 3%;
  }

  div[itemprop=&#39;articleBody&#39;] {
    margin: auto;
    max-width: 36em;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h2 id=&#34;small-viewports&#34;&gt;Small viewports&lt;/h2&gt;
&lt;p&gt;People read on a variety of viewport sizes. Page structure must be simple enough to handle these layouts smoothly.&lt;/p&gt;
&lt;h3 id=&#34;narrow-viewports-are-popular&#34;&gt;Narrow viewports are popular&lt;/h3&gt;
&lt;p&gt;Not every phone has a giant screen: millions of people around the world use Web-enabled feature phones. The Jio Phone 2, for instance, is narrow enough to fall through a belt loop: it sports a screen that&amp;rsquo;s just over 3.6 cm (1.44 inches) wide. Furthermore, some programs sport browser windows in sidebars (c.f. Mozilla&amp;rsquo;s &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/side-view/&#34;&gt;side view&lt;/a&gt;, Vivaldi &lt;a href=&#34;https://help.vivaldi.com/desktop/panels/web-panels/&#34;&gt;Web Panels&lt;/a&gt;). Users who leverage floating or tiling windows rather than maximizing everything could use viewports of arbitrary dimensions.&lt;/p&gt;
&lt;p&gt;Nowadays, even tiny smartwatches have built-in browsers; users who navigate to links in smartwatch message and email apps will use simplified browsers that fit on their wrists. Apple published a &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2018/239/&#34;&gt;video about WebKit on WatchOS&lt;/a&gt; (here&amp;rsquo;s &lt;a href=&#34;https://brucelawson.co.uk/2018/the-practical-value-of-semantic-html/&#34;&gt;a text summary of the video&lt;/a&gt;, starting at the &amp;ldquo;New types of devices&amp;rdquo; section). The Apple Watch Series 6 has a viewport that&amp;rsquo;s 162 CSS pixels wide; it emulates an iPhone&amp;rsquo;s viewport and shows a zoomed-out version of the page unless the page includes a &amp;ldquo;device-adjust&amp;rdquo; meta tag, the same way phones emulate desktop viewports without a &amp;ldquo;viewport&amp;rdquo; meta tag. Samsung Internet is a popular option for Wear OS users, whose viewports are often just 150 CSS pixels.&lt;/p&gt;
&lt;h3 id=&#34;wide-items&#34;&gt;Wide items&lt;/h3&gt;
&lt;p&gt;A single element wider than the viewport will trigger horizontal scrolling for the entire page. This is especially problematic for long pages that already require excessive vertical scrolling.&lt;/p&gt;
&lt;p&gt;Long words, especially in headings, can trigger horizontal overflow. Test in a viewport that&amp;rsquo;s under 240 pixels wide (&lt;abbr title=&#34;Device Pixel Ratio&#34;&gt;DPR&lt;/abbr&gt;=1) and observe any words that trail off of the edge of the screen. Add soft hyphens to these words using the &lt;code&gt;&amp;amp;shy;&lt;/code&gt; entity.&lt;/p&gt;
&lt;p&gt;Most modern browsers support the &lt;code&gt;hyphens&lt;/code&gt; CSS 3 property, but full automatic hyphenation is usually an overkill solution with a naive implementation. Automatic hyphenation will insert hyphens wherever it can, not necessarily between the best syllables. At the time of writing, humans are still better at hyphenating than most software implementations. I only enable full hyphenation on the narrowest of viewports.&lt;/p&gt;
&lt;p&gt;Users employing machine translation will not benefit from your soft hyphens, so don&amp;rsquo;t expect them to always work as intended. Translation tools might also replace short words with long ones. Soft hyphens and automatic hyphenation are both flawed solutions, but I find soft hyphens to be less problematic.&lt;/p&gt;
&lt;p&gt;Where long inline &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; elements can trigger horizontal scrolling, consider a scrollable &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; element instead. Making a single element horizontally scrollable is far better than making the entire page scrollable in two dimensions. Hard-wrap code blocks so that they won&amp;rsquo;t horizontally scroll in most widescreen desktop browsers.&lt;/p&gt;
&lt;p&gt;Be sure to test your hyphens with NVDA or Windows Narrator: these screen readers&amp;rsquo; pronunciation of words can be disrupted by poorly-placed hyphens. Balancing the need to adapt to narrow screens against the need to sound correctly to a screen reader is a complex matter.&lt;sup id=&#34;fnref:35&#34;&gt;&lt;a href=&#34;#fn:35&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;35&lt;/a&gt;&lt;/sup&gt; The best place to insert a hyphen is between compound words. For example, splitting &amp;ldquo;Firefighter&amp;rdquo; into &amp;ldquo;Fire-fighter&amp;rdquo; is quite safe. Beyond that, try listening to hyphenated words in NVDA to ensure they remain clear.&lt;/p&gt;
&lt;h3 id=&#34;keeping-text-together&#34;&gt;Keeping text together&lt;/h3&gt;
&lt;p&gt;Soft hyphens are great for splitting up text, but some text should stay together. The phrase &amp;ldquo;10 cm&amp;rdquo;, for instance, would flow poorly if &amp;ldquo;10&amp;rdquo; and &amp;ldquo;cm&amp;rdquo; appeared on separate lines. Splitting text becomes especially painful on narrow viewports. A non-breaking space keeps the surrounding text from being re-flowed. Use the &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt; HTML entity instead of a space: &lt;code&gt;10&amp;amp;nbsp;cm&lt;/code&gt;. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://practicaltypography.com/&#34;&gt;Practical Typography&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://mbtype.com/bio.html&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Matthew&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Butterick&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;, describes &lt;a href=&#34;https://briefs.video/videos/is-progressive-enhancement-dead-yet/&#34;&gt;where to use the non-breaking space&lt;/a&gt; in more detail.&lt;/p&gt;
&lt;p&gt;One exception to the rules from &lt;cite&gt;Practical Typography&lt;/cite&gt;: don&amp;rsquo;t use a non-breaking space if it would trigger two-dimensional scrolling on a narrow viewport. Between broken text and two-dimensional scrolling, broken text is the lesser evil. I personally set a cutoff at 2.5 cm (1 inch) at 125% zoom.&lt;/p&gt;
&lt;h3 id=&#34;pictures-of-text&#34;&gt;Pictures of text&lt;/h3&gt;
&lt;p&gt;You should only use pictures of text when the visual presentation of the text is part of the information you&amp;rsquo;re trying to convey. Always be sure to test how such an image looks on a narrow screen.&lt;/p&gt;
&lt;p&gt;Images do not reflow their text. When the viewport is narrower than the image dimensions, you can instruct the browser to do one of three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Allow the image to exceed the viewport width, triggering two-dimensional scrolling for the whole page.&lt;/li&gt;
&lt;li&gt;Shrink the image to fit the viewport, causing the text in the image to shrink with it.&lt;/li&gt;
&lt;li&gt;Allow the image to horizontally overflow.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I already covered the first option in the prior subsection. If you expect viewers to read the text in the image and you don&amp;rsquo;t link an image transcript, the second option isn&amp;rsquo;t ideal. Overflow is almost never what we want.&lt;/p&gt;
&lt;p&gt;The best compromise is to ensure that the image isn&amp;rsquo;t too wide, and can support large text on a narrow viewport. Lines of text in images should contain as few characters as possible. For a good example, see the &amp;ldquo;&lt;a href=&#34;#in-defense-of-link-underlines&#34;&gt;In defense of link underlines&lt;/a&gt;&amp;rdquo; section.&lt;/p&gt;
&lt;p&gt;If the text needs to be readable, &lt;a href=&#34;#use-the-advanced-perceptual-contrast-algorithm&#34;&gt;check its APCA levels&lt;/a&gt;. At large sizes, the contrast shouldn&amp;rsquo;t be too high; at small sizes, it shouldn&amp;rsquo;t be too low.&lt;/p&gt;
&lt;h3 id=&#34;indented-elements&#34;&gt;Indented elements&lt;/h3&gt;
&lt;p&gt;Most browser default stylesheets were not optimized for narrow viewports, so narrow-viewport optimization is one of few good reasons to override the defaults. The best example of widescreen bias in browser stylesheets is indentation.&lt;/p&gt;
&lt;p&gt;The HTML standard&amp;rsquo;s section 4.4.4 &lt;a href=&#34;https://html.spec.whatwg.org/multipage/grouping-content.html#the-blockquote-element&#34;&gt;covers blockquotes&lt;/a&gt;. It recommends placing a &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; element inside a &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; and citations in a &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt; to show a semantic relationship between a quotation and its citation.&lt;/p&gt;
&lt;p&gt;Browser default stylesheets typically give &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; elements extra margins on either side. &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; elements have a large indent. Combining these two properties gives the final quotation an excessive visual indent, wasting precious vertical screen space. When quoted text contains list elements (&lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;dl&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;), the indentation alone may fill most of a narrow viewport!&lt;/p&gt;
&lt;p&gt;I chose to remove the margins in &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; elements for quotations and code snippets. If you&amp;rsquo;re reading this page with its own stylesheet enabled, in a CSS 2 compliant browser, you might have noticed the blockquotes on it have a minimal indent and a thick border on the left rather than a full indent. These two adjustments allow blockquotes containing bulleted lists to fit on most narrow viewports, even when wrapped by a &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;p&gt;Indented elements can be difficult to distinguish when nested. A &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; may not be visible if it contains an &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;. My left-border approach resolves this ambiguity.&lt;/p&gt;
&lt;p&gt;Another example: outside the Web, I prefer indenting code with tabs instead of spaces. Tab widths are user-configurable, while spaces aren&amp;rsquo;t. HTML pre-formatted code blocks, however, are best indented with two spaces. Default browser stylesheets typically represent tabs with an excessive indent, which can be annoying on narrow viewports.&lt;/p&gt;
&lt;h3 id=&#34;short-viewports&#34;&gt;Short viewports&lt;/h3&gt;
&lt;p&gt;Designers often use figures to &amp;ldquo;break up&amp;rdquo; their content, and provide negative space. This is good advice, but I don&amp;rsquo;t think people pay enough attention to the flipside: splitting up content with too many figures can make reading extremely painful on a short viewport. Design maxims usually lack nuance.&lt;/p&gt;
&lt;p&gt;Small phones typically support display rotation. When phones switch to landscape-mode, vertical space becomes precious. Fixed elements (e.g. dickbars) become a major usability hazard. Ironically, the WCAG&amp;rsquo;s own interactive Techniques reference is a perfect example of how fixed elements impact usability on short screens.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/wcag_quickref_dark.3310425969.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/wcag_quickref_dark.1453920755.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/wcag_quickref.347093243.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/wcag_quickref.987828208.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;540&#34; height=&#34;293&#34;
src=&#34;https://envs.net/~seirdy/p/wcag_quickref.987828208.png&#34; alt=&#34;Website with banner covering top half of screen.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;When filtering criteria on &lt;a href=&#34;https://www.w3.org/WAI/WCAG22/quickref/?currentsidebar=%23col_customize&amp;amp;showtechniques=134%2C124&amp;amp;levels=a&amp;amp;technologies=js%2Cserver%2Csmil%2Cpdf%2Cflash%2Csl&#34;&gt;the Quickref Reference page&lt;/a&gt;, a dickbar lists active filters. I increased the zoom level; you may have to add more filters to fill the screen with a smaller font.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;Keeping the most important content above the fold (the part of the page that&amp;rsquo;s visible without scrolling) is hard on small screens. Nonetheless, it&amp;rsquo;s an important element of cognitive accessibility. Users may struggle to identify a page or navigate a site if the title and navigation links are below the fold. &lt;a href=&#34;https://www.w3.org/TR/mobile-accessibility-mapping/#positioning-important-page-elements-before-the-page-scroll&#34;&gt;The &lt;abbr title=&#34;Web Accessibility Initiative&#34;&gt;WAI&amp;rsquo;s&lt;/abbr&gt; mobile accessibility guidelines&lt;/a&gt; share this recommendation.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Make important tasks and features on the site stand out and easy to find.&lt;/p&gt;
&lt;p&gt;This includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[…]&lt;/li&gt;
&lt;li&gt;Placing the tasks/features towards the top of the page so the user does not have to scroll to see them.&lt;/li&gt;
&lt;li&gt;Placing the tasks/features toward the top of the content so assistive technology finds them quickly.&lt;/li&gt;
&lt;li&gt;[…]&lt;/li&gt;
&lt;li&gt;Including key tasks at a top level of the main navigation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;Making Content Usable for People with Cognitive and Learning Disabilities&lt;/cite&gt;, section 4.3.1:
&lt;a href=&#34;https://www.w3.org/TR/coga-usable/#what-to-do-6&#34;&gt;Make it Easy to Find the Most Important Tasks and Features of the Site&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h2 id=&#34;spacing&#34;&gt;Spacing&lt;/h2&gt;
&lt;p&gt;The previous &lt;a href=&#34;#small-viewports&#34;&gt;&amp;ldquo;small viewports&amp;rdquo; section&lt;/a&gt; may tempt you to make your content as dense as possible. Please don&amp;rsquo;t overdo it.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an ideal range somewhere between &amp;ldquo;cramped&amp;rdquo; and &amp;ldquo;spaced-apart&amp;rdquo; content. Finding this range is difficult. The best way to resolve such difficult and subjective issues is to ask your readers for feedback, giving disproportionate weight to readers with under-represented needs (especially disabled readers).&lt;/p&gt;
&lt;h3 id=&#34;non-interactive-space&#34;&gt;Non-interactive space&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;#indented-elements&#34;&gt;Excessive indentation makes reading difficult&lt;/a&gt; on narrow viewports, but preserving some indentation is still useful.&lt;/p&gt;
&lt;p&gt;For now, I&amp;rsquo;ve decided to keep some indentation on list elements (&lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;dl&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;) since I often fill them with links (see this article&amp;rsquo;s &lt;a href=&#34;#TableOfContents&#34;&gt;table of contents&lt;/a&gt; for an example). This indentation provides important non-interactive negative space.&lt;/p&gt;
&lt;p&gt;Readers with hand tremors depend on this space to scroll without accidentally selecting an interactive element; &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span&gt;Axess Lab&lt;/span&gt; described the issue in &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://axesslab.com/hand-tremors/&#34;&gt;Hand Tremors and the giant button problem&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. Readers who double-tap to jump or zoom can&amp;rsquo;t do so if there&amp;rsquo;s no screen region that&amp;rsquo;s &amp;ldquo;safe to tap&amp;rdquo;. Having clearly distinguished links also helps users decide safe places to tap the screen; see the &lt;a href=&#34;#in-defense-of-link-underlines&#34;&gt;section on link underlines&lt;/a&gt; for more information.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/touch_targets_dark.1853396414.avif&#34;
type=&#34;image/avif&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/touch_targets_dark.1723457243.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/touch_targets.1549842986.avif&#34;
type=&#34;image/avif&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/touch_targets.2433311592.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;280&#34; height=&#34;320&#34;
src=&#34;https://envs.net/~seirdy/p/touch_targets.2433311592.png&#34; alt=&#34;List of rectangles with a 56 pixel wide square to its left, filling negative space.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;I made sure to leave enough non-interactive space in &lt;a href=&#34;https://envs.net/~seirdy/~seirdy/#webrings&#34;&gt;my homepage&amp;rsquo;s webring list&lt;/a&gt; to accommodate a 48 px tap target, with extra space in between.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;Always make sure one non-interactive region exists on the screen at a time, 48 CSS pixels in either dimension; that&amp;rsquo;s the size of a &lt;a href=&#34;#google-tap-target&#34;&gt;tap target&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;tap-targets&#34;&gt;Tap targets&lt;/h3&gt;
&lt;p&gt;Tap targets should be at least 44 pixels tall and wide &lt;a href=&#34;https://www.w3.org/TR/WCAG22/#target-size-enhanced&#34;&gt;according to the WCAG&lt;/a&gt;; this is large enough to easily tap on a touchscreen. The WCAG makes an exception for inline targets, like links in a paragraph.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://web.dev/tap-targets/&#34; title=&#34;{id=&amp;#39;google-tap-target&amp;#39;}&#34;&gt;Google has more aggressive tap-target recommendations&lt;/a&gt;: it recommends raising the limit 48 px with with 8 px gaps, going so far as to make tap target size a ranking factor in search.&lt;/p&gt;
&lt;p&gt;The edges of a touch screen are often tap-targets (the top edge might toggle navigation or scroll to the top, the bottom may have home/back buttons, and the right side may have a scrollbar), so keep elements slightly away from those. Keeping away from edges is doubly important on phones: they may have rounded edges that are easy to miss-tap, or reinforced cases that make the very edge of a screen difficult to reach.&lt;/p&gt;
&lt;p&gt;On lists with many links, I had to find other ways to ensure adequate tap-target size and provide sufficient non-interactive space for readers with hand-tremors to scroll. Some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&#34;#webmentions&#34;&gt;webmention list&lt;/a&gt; after this article separates links with timestamps and some paragraph spacing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some list items have links with extra padding. These include description terms (&lt;code&gt;&amp;lt;dt&amp;gt;&lt;/code&gt;) and navigation elements, such as the table of contents or the site header and footer,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&#34;https://envs.net/~seirdy/&#34;&gt;posts list&lt;/a&gt; and the list of related articles at the beginning of &lt;a href=&#34;https://envs.net/~seirdy/2022/02/02/floss-security/&#34;&gt;one of my posts&lt;/a&gt; separates links with non-interactive text descriptions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This list separates two list-items containing links with a third list-item that lacks links.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;line-spacing&#34;&gt;Line spacing&lt;/h3&gt;
&lt;p&gt;Increasing the line-spacing a bit will make tap targets larger and improve comprehension by readers with cognitive disabilities. A WCAG AAA Success Criterion is to allow 1.5 space units between lines; the &lt;abbr title=&#34;Web Accessibility Initiative&#34;&gt;WAI&lt;/abbr&gt;&amp;rsquo;s Cognitive and Learning Disabilities Accessibility Task Force &lt;a href=&#34;https://w3c.github.io/coga/extension/#changedlevels&#34;&gt;recommends changing this Success Criterion&amp;rsquo;s level&lt;/a&gt;, finding it too important to be relegated to AAA status.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Line spacing (leading) is at least space-and-a-half within paragraphs, and paragraph spacing is at least 1.5 times larger than the line spacing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/TR/WCAG22/&#34;&gt;WCAG 2.2&lt;/a&gt;&lt;/cite&gt;,
&lt;a href=&#34;https://w3c.github.io/wcag/guidelines/22/#visual-presentation&#34;&gt;Success Criterion 1.4.8 Visual Presentation&lt;/a&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;non-browsers-reading-mode&#34;&gt;Non-&lt;wbr /&gt;browsers: reading mode&lt;/h2&gt;
&lt;p&gt;Fully standards-compliant browsers aren&amp;rsquo;t the only programs people use. They also use &amp;ldquo;reading mode&amp;rdquo; tools and services.&lt;/p&gt;
&lt;p&gt;Reading modes leverage article extractors such as &lt;span translate=&#34;no&#34;&gt;&lt;a href=&#34;https://github.com/mozilla/readability&#34;&gt;Readability&lt;/a&gt;&lt;/span&gt; (integrated into Firefox, Epiphany, Brave, Vivaldi, and others), &lt;a href=&#34;https://chromium.googlesource.com/chromium/dom-distiller/&#34;&gt;DOM Distiller&lt;/a&gt; (integrated into Chromium), &lt;a href=&#34;https://github.com/brave/brave-core/tree/master/components/speedreader/rust/lib&#34;&gt;Brave SpeedReader&lt;/a&gt;, and &lt;a href=&#34;https://trafilatura.readthedocs.io/en/latest/&#34;&gt;Trafilatura&lt;/a&gt; (powers a variety of tools and services). A host of other proprietary options exist: Diffbot powers services like Instapaper, Mozilla&amp;rsquo;s Pocket has its own secret parsers, and countless &amp;ldquo;send to e-reader&amp;rdquo; services have amassed loyal users. Safari&amp;rsquo;s proprietary fork of &lt;span translate=&#34;no&#34;&gt;Readability&lt;/span&gt; has grown quite complex compared to upstream; Edge&amp;rsquo;s Immersive Reader is &lt;a href=&#34;https://techcommunity.microsoft.com/t5/discussions/documentation-on-huerestics-used-during-article-distillation-in/m-p/3266436&#34;&gt;a mystery to me&lt;/a&gt;, with &lt;a href=&#34;https://feedbackportal.microsoft.com/feedback/idea/e0d9b299-e3b6-ec11-a81c-000d3a7ce453&#34;&gt;a problematic stylesheet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t recommend catering to each tool&amp;rsquo;s non-standard quirks. Studying their design reveals that they observe open standards, to varying degrees. &lt;span translate=&#34;no&#34;&gt;Readability&lt;/span&gt;, DOM Distiller, and Trafilatura understand plain-old, semantic HTML (&lt;abbr title=&#34;Plain-Old, Semantic HTML&#34;&gt;POSH&lt;/abbr&gt;).&lt;/p&gt;
&lt;p&gt;POSH should be enough for most use-cases, but some authors want to go further. For example, they may want a byline or published date to show up in these modes.&lt;/p&gt;
&lt;p&gt;Most extractors fetch these values using open standards for structured data. The most well-supported option is &lt;a href=&#34;https://microformats.org/wiki/microformats&#34;&gt;microformats&lt;/a&gt; (&lt;span translate=&#34;no&#34;&gt;Readability&lt;/span&gt; is one of the few that supports the newer microformats2). Some support &lt;a href=&#34;https://schema.org/&#34;&gt;schema.org&lt;/a&gt; vocabularies in microdata or JSON-LD syntaxes, or &lt;a href=&#34;https://www.dublincore.org/&#34;&gt;Dublin Core&lt;/a&gt; vocabularies in RDFa. Most parse &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tags from the document &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, but others don&amp;rsquo;t due to misuse and overly aggressive &lt;abbr title=&#34;Search Engine Optimization&#34;&gt;SEO&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;Sorry, that was a lot of jargon for a single paragraph. Unfortunately, describing those terms is out of scope for this post. If you&amp;rsquo;d like to dive down this rabbit hole, read about the &amp;ldquo;Semantic Web&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Some reading-mode implementations also support &lt;a href=&#34;https://www.w3.org/TR/dpub-aria-1.1/&#34;&gt;DPUB-ARIA&lt;/a&gt;, but I&amp;rsquo;d caution against using ARIA when POSH is sufficient: &amp;ldquo;bad ARIA&amp;rdquo; can be far more harmful to screen readers than &amp;ldquo;no ARIA&amp;rdquo;. Only use ARIA to fill in gaps left by POSH.&lt;/p&gt;
&lt;p&gt;Again: avoid catering to non-standard implementations&amp;rsquo; quirks, especially undocumented proprietary ones. Let&amp;rsquo;s not repeat the history of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Browser_wars&#34;&gt;browser wars&lt;/a&gt;. Remember that some implementations have bugs; consider reporting issues when one arises. More information about standard and non-standard behavior of reading modes is in the article &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.ctrl.blog/entry/browser-reading-mode-parsers.html&#34;&gt;Web Reading Mode: The non-standard rendering mode&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.daniel.priv.no/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Daniel&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Aleksandersen&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Reading modes aren&amp;rsquo;t the only non-browser user agents out there. Plain-text feed readers and link previewers are some other options. I singled out reading modes because of their widespread adoption and value. Decide which other kinds of agents are important to you (if any), and see if they expose a hole in your semantics.&lt;/p&gt;
&lt;h2 id=&#34;machine-translation&#34;&gt;Machine translation&lt;/h2&gt;
&lt;p&gt;Believe it or not, the entire world doesn&amp;rsquo;t speak your website&amp;rsquo;s languages. Browsers like Chromium, Microsoft Edge, and Safari have integrated machine translation to translate entire pages. Users can also leverage online website translators such as Google Translate or Bing. These &amp;ldquo;webpage translators&amp;rdquo; are far more complex than their plain-text predecessors.&lt;/p&gt;
&lt;p&gt;Almost every word on your site can be re-written. Prepare for headings to change length, paragraphs to grow and shrink, or hyphenation to disappear. Your site&amp;rsquo;s layout should make sense even when the length of each textual element is changed.&lt;/p&gt;
&lt;p&gt;Machines can&amp;rsquo;t reliably translate images of text, since OCR is error-prone. See the &lt;a href=&#34;#image-transcripts&#34;&gt;image transcripts section&lt;/a&gt; for remedies.&lt;/p&gt;
&lt;p&gt;Incorrect spelling and poor grammar in an original work can reduce the accuracy of a machine-translated derivative. Be sure to proofread.&lt;/p&gt;
&lt;h3 id=&#34;posh-helps-translation-engines&#34;&gt;POSH helps translation engines&lt;/h3&gt;
&lt;p&gt;To ensure that pages get machine-translated properly, make proper use of semantic HTML. Daniel wrote about this topic too in &lt;cite&gt;&lt;a href=&#34;https://www.ctrl.blog/entry/html-semantic-improve-machine-translation.html&#34;&gt;Semantic markup improves the quality of machine-translated texts&lt;/a&gt;&lt;/cite&gt;; I highly encourage giving his article a read.&lt;/p&gt;
&lt;p&gt;Elements to pay close attention to include &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;samp&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;var&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;abbr&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;address&amp;gt;&lt;/code&gt;. The semantic information conveyed by these elements supplies important context to translation algorithms.&lt;/p&gt;
&lt;p&gt;Only after &lt;abbr title=&#34;Plain-Old, Semantic HTML&#34;&gt;POSH&lt;/abbr&gt; is insufficient should you attempt to &amp;ldquo;override&amp;rdquo; behavior with the &lt;code&gt;translate&lt;/code&gt; HTML attribute. Setting &lt;code&gt;translate=&amp;quot;no&amp;quot;&lt;/code&gt; or &lt;code&gt;translate=&amp;quot;yes&amp;quot;&lt;/code&gt; should override the behavior of standards-compliant translation engines. If you&amp;rsquo;re unsure whether or not to use a &lt;code&gt;translate&lt;/code&gt; attribute, search the relevant word or phrase on &lt;a href=&#34;https://www.keybot.com/&#34;&gt;Keybot&lt;/a&gt; to see how human translators approached it.&lt;/p&gt;
&lt;p&gt;For example: machine translation will leave &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;samp&amp;gt;&lt;/code&gt; blocks as-is. Perhaps you could annotate comments within code with a &lt;code&gt;translate=&amp;quot;yes&amp;quot;&lt;/code&gt; attribute. However, translation engines should leave variables within those comments as-is.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://developers.google.com/style/placeholders&#34;&gt;Google&amp;rsquo;s style guide&lt;/a&gt; recommends annotating format placeholders in code blocks with the &lt;code&gt;&amp;lt;var&amp;gt;&lt;/code&gt; element; consider doing so and adding a &lt;code&gt;translate=&amp;quot;yes&amp;quot;&lt;/code&gt; attribute to placeholder values, at your discretion. For an example, check this article&amp;rsquo;s code sample &lt;a href=&#34;#png-pipeline&#34;&gt;describing my PNG optimization pipeline&lt;/a&gt;. Most implementations do not yet support &lt;code&gt;translate=&amp;quot;yes&amp;quot;&lt;/code&gt; embedded inside untranslated blocks, but I&amp;rsquo;m counting on this changing.&lt;/p&gt;
&lt;h3 id=&#34;changing-text-direction&#34;&gt;Changing text direction&lt;/h3&gt;
&lt;p&gt;Consider the implications of translating between left-to-right (LTR) and right-to-left (RTL) languages. Do a search through your stylesheets for keywords like &amp;ldquo;left&amp;rdquo; and &amp;ldquo;right&amp;rdquo; to ensure that styles don&amp;rsquo;t depend too heavily on text direction. Once you&amp;rsquo;ve cleared the low-hanging fruit, try translating the page to a language like Arabic.&lt;/p&gt;
&lt;p&gt;Websites following this page&amp;rsquo;s layout advice shouldn&amp;rsquo;t need much adjustment. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://ishadeed.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Ahmed&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Shadeed&lt;/span&gt;&lt;/span&gt;’s&lt;/a&gt;&lt;/span&gt; &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://rtlstyling.com/posts/rtl-styling/&#34;&gt;RTL Styling 101&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; is a comprehensive guide to what can go wrong and how to fix issues.&lt;/p&gt;
&lt;h3 id=&#34;current-limitations&#34;&gt;Current limitations&lt;/h3&gt;
&lt;p&gt;Machine translation is always improving. Today, it has some limitations which I expect will be resolved with time.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;translate=&amp;quot;yes&amp;quot;&lt;/code&gt; attributes nested inside un-translated blocks (code snippets, blocks with &lt;code&gt;translate=&amp;quot;no&amp;quot;&lt;/code&gt;, etc.) are not yet supported by most translation tools. It&amp;rsquo;s a relatively new attribute, so flaky support is understandable.&lt;/p&gt;
&lt;p&gt;Machine translators often skip &lt;code&gt;aria-label&lt;/code&gt; and &lt;code&gt;aria-description&lt;/code&gt;. For this reason, authors prefer using &lt;code&gt;aria-labelledby&lt;/code&gt; and &lt;code&gt;aria-describedby&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Microsoft Edge is the only browser I know of to adjust text-direction during translation, but it breaks when faced with inline &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
&lt;h2 id=&#34;inaccessible-default-stylesheets&#34;&gt;In­accessible default stylesheets&lt;/h2&gt;
&lt;p&gt;Simple sites should err on the side of respecting default stylesheets. With rare exceptions, there are only two times I feel comfortable overriding default stylesheets:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Gently adjusting a parameter rather than completely changing an element&amp;rsquo;s appearance. Typically, this involves adjusting dimensions.&lt;/li&gt;
&lt;li&gt;Fundamentally altering an element&amp;rsquo;s appearance. I only feel comfortable doing this when the defaults are truly inaccessible, or clash with another accessibility enhancement I made.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My previous advice regarding line spacing and maximum line length fell in the first category. My approach to re-styling &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; elements, adding borders, and using &lt;code&gt;sans-serif&lt;/code&gt; fell in the latter category.&lt;/p&gt;
&lt;p&gt;This section contains miscellaneous advice regarding the latter category of stylesheet overrides.&lt;/p&gt;
&lt;h3 id=&#34;monospace-handling&#34;&gt;Mono­space handling&lt;/h3&gt;
&lt;p&gt;By default, most browsers render monospace text at a reduced size. If you want your monospace text to be readable, set its font family to &lt;code&gt;monospace, monospace&lt;/code&gt; (sic).&lt;/p&gt;
&lt;p&gt;Font family alone is not enough to distinguish an element from its surroundings. For &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;samp&amp;gt;&lt;/code&gt; elements, I recommend supplementing the font family change with a soft border. As described in &lt;a href=&#34;#color-overrides-and-accessibility&#34;&gt;the &amp;ldquo;Color overrides and accessibility&amp;rdquo; section&lt;/a&gt;, borders are preferable to background colors because they don&amp;rsquo;t override the user-agent&amp;rsquo;s preferred foreground and background colors.&lt;/p&gt;
&lt;p&gt;Finally, it&amp;rsquo;s important to distinguish &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt; from &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;samp&amp;gt;&lt;/code&gt;, and regular body text.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
&lt;figcaption id=&#34;code-20-caption&#34;&gt;
	&lt;span id=&#34;code-20&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 20&lt;/strong&gt; (&lt;span&gt;CSS&lt;/span&gt;)&lt;/span&gt;:
How I distinguish &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;samp&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt; from each other and from body text.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;code, kbd, samp {
  font-family: monospace, monospace;
}

pre,
:not(pre) &amp;gt; code, :not(pre) &amp;gt; samp {
  border: 1px solid;
}

/* Dark borders in text are harsh */
:not(pre) &amp;gt; code, :not(pre) &amp;gt; samp {
  border-color: #999;
}

kbd {
  font-weight: bold;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;h3 id=&#34;focus-indicators&#34;&gt;Focus indicators&lt;/h3&gt;
&lt;p&gt;The default focus indicators are hard to see in certain browsers (e.g. Firefox and WebKit), especially when the focused element already has a border. We can override them to make them more accessible.&lt;/p&gt;
&lt;figure&gt;
&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus_dark.2482216229.webp&#34;
type=&#34;image/webp&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus_dark.372556353.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/focus.1658875539.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img
width=&#34;241&#34; height=&#34;220&#34;
src=&#34;https://envs.net/~seirdy/p/focus.1658875539.png&#34; alt=&#34;Screenshots of link outlines: one thin and dotted, one thick and solid.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;Firefox 99&amp;rsquo;s default focus indicator, before and after my adjustments.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;On one hand, users who need enhanced focus visibility may override the default focus indicators in their browser preferences; I&amp;rsquo;d like to support such overrides. On the other hand, relying on these customizations would violate the &amp;ldquo;accessible by default&amp;rdquo; directive. This would exclude Tor Browser and fingerprinting-averse readers, as well as anybody who has to borrow a machine or browser they don&amp;rsquo;t own or haven&amp;rsquo;t customized yet. This is another one of the few areas where I&amp;rsquo;d recommend overriding browser default stylesheets.&lt;/p&gt;
&lt;p&gt;The WCAG &lt;a href=&#34;https://w3c.github.io/wcag/guidelines/22/#focus-appearance-enhanced&#34;&gt;Success Criterion 2.4.12&lt;/a&gt; recommends making focus indicators 2 px thick. While this success criterion is only AAA-level, it&amp;rsquo;s easy enough to meet and beneficial enough to others that we should all meet it.&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;:focus&lt;/code&gt; and &lt;code&gt;:focus-visible&lt;/code&gt; to highlight selected and keyboard-focused elements, respectively. Take care to only alter styling, not behavior: only keyboard-focusable elements should receive outlines. Modern browser stylesheets use &lt;code&gt;:focus-visible&lt;/code&gt; instead of &lt;code&gt;:focus&lt;/code&gt;; old browsers only support &lt;code&gt;:focus&lt;/code&gt; and re-style a subset of focusable elements. Your stylesheets should do the same, to match browser behavior.&lt;sup id=&#34;fnref:36&#34;&gt;&lt;a href=&#34;#fn:36&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;36&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
&lt;figcaption id=&#34;code-21-caption&#34;&gt;
	&lt;span id=&#34;code-21&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 21&lt;/strong&gt; (&lt;span&gt;CSS&lt;/span&gt;)&lt;/span&gt;:
I do not re-style &lt;code&gt;:focus&lt;/code&gt; when &lt;code&gt;:focus-visible&lt;/code&gt; works, to match existing behavior. I also override &lt;code&gt;:focus&lt;/code&gt; styling only on the subset of focusable elements that would normally show an outline. Based on the post &lt;span
class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.tpgi.com/focus-visible-and-backwards-compatibility/&#34;&gt;:focus-visible and backwards compatibility&lt;/a&gt;&lt;/cite&gt; by &lt;span class=&#34;h-card vcard p-author&#34;&gt; &lt;a href=&#34;https://www.tpgi.com/&#34; class=&#34;u-url url&#34;&gt; &lt;span class=&#34;p-name&#34;&gt;TPGi&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;a:focus,
[tabindex]:focus {
  outline: 3px solid;
}

@supports selector(:focus-visible) {
  a:focus:not(:focus-visible),
  [tabindex]:focus:not(:focus-visible) {
    outline: none;
  }
}

:focus-visible {
  outline: 3px solid;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;p&gt;&lt;ins&gt;Update: Firefox 104 has adopted a much better 2-color focus indicator; supplying a custom indicator will be less important in 2023 once a Firefox ESR version above 104 becomes available.&lt;/ins&gt;&lt;/p&gt;
&lt;h2 id=&#34;screen-reader-improvements&#34;&gt;Screen reader improve­ments&lt;/h2&gt;
&lt;p&gt;This section focuses on ways to improve screen reader support that have not already been covered. The most important measures (semantic HTML, good alt-text and image context, correct spelling, etc.) have already been covered in previous sections.&lt;/p&gt;
&lt;figure id=&#34;straw-analogy&#34; tabindex=&#34;-1&#34;&gt;
&lt;blockquote&gt;
	&lt;p&gt;Try reading your screen through a drinking straw for an hour to get an idea of the limited context that a blind user has. You simply cannot scan the entire page at a glance with a screenreader - you have to listen to the structure of it carefully and remember all that, or read through the entire thing to find stuff, unless there are explicit associations such as longdesc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard&#34;&gt;&lt;a href=&#34;https://www.w3.org/People/Charles/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Charles&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;McCathieNevile&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://lists.w3.org/Archives/Public/public-html/2008Feb/0061.html&#34;&gt;longdesc Re: Clarification of rational for deprecation&amp;hellip;&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&#34;split-elements-and-possessive-hyperlinks&#34;&gt;Split elements and possessive hyperlinks&lt;/h3&gt;
&lt;p&gt;Some screen readers split up sections by HTML elements. This means HTML elements in the middle of a sentence will trigger pauses. The problem comes up frequently on sites that use excessive inline formatting.&lt;/p&gt;
&lt;p&gt;This is especially concerning on my website, where I tend to hyperlink peoples&amp;rsquo; names (a common practice on the IndieWeb): making names possessive with an &amp;ldquo;apostrophe + s&amp;rdquo; creates pronunciation issues. &amp;ldquo;Seirdy&amp;rsquo;s Home&amp;rdquo; could be read as &amp;ldquo;Seirdy. Link. S. Home&amp;rdquo; if the word &amp;ldquo;Seirdy&amp;rdquo; is a hyperlink.&lt;/p&gt;
&lt;p&gt;A workaround is to use the &amp;ldquo;text&amp;rdquo; ARIA role to remove the semantics of elements. This workaround doesn&amp;rsquo;t work in certain screen readers, including Orca, so don&amp;rsquo;t count on it.&lt;/p&gt;

&lt;figure aria-labelledby=&#34;code-1&#34;&gt;
 &lt;figcaption id=&#34;code-22-caption&#34;&gt;
	&lt;span id=&#34;code-22&#34; tabindex=&#34;-1&#34;&gt;
	&lt;strong&gt; &lt;span&gt;Code snippet&lt;/span&gt; 22&lt;/strong&gt; (&lt;span&gt;HTML&lt;/span&gt;)&lt;/span&gt;:
An example of using &lt;code&gt;role=&amp;quot;text&amp;quot;&lt;/code&gt; to prevent splitting in a multi-line heading. By &lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://axesslab.com/author/hampelusken/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Hampus&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Sethfords&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
from &lt;span class=&#34;p-org org&#34;&gt;
&lt;a class=&#34;organization-name&#34; href=&#34;https://axesslab.com&#34;&gt;
&lt;span&gt;Axess Lab&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;, &lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://axesslab.com/text-splitting/&#34;&gt;Text Splitting Causes Screen Reader Problems&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;h1&amp;gt;
  &amp;lt;span role=&amp;quot;text&amp;quot;&amp;gt;Digital accessibility, &amp;lt;br&amp;gt;
    for everyone.
  &amp;lt;/span&amp;gt;
&amp;lt;/h1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/figure&gt;

&lt;p&gt;If you&amp;rsquo;re unfamiliar with ARIA, always remember the &lt;dfn id=&#34;first-rule-of-aria&#34; tabindex=&#34;-1&#34;&gt;First Rule of ARIA&lt;/dfn&gt;: &lt;a href=&#34;https://www.w3.org/TR/wai-aria-practices-1.1/#no_aria_better_bad_aria&#34;&gt;No ARIA is better than Bad ARIA&lt;/a&gt;. ARIA exposes a host of accessibility hazards when used improperly, so only use this approach when there&amp;rsquo;s no good alternative. Furthermore, &lt;code&gt;role=&amp;quot;text&amp;quot;&lt;/code&gt; isn&amp;rsquo;t actually standard ARIA; its proposed inclusion into the ARIA specification was controversial. See &lt;a href=&#34;https://github.com/w3c/aria/issues/870#issuecomment-589282781&#34;&gt;issue 870 of WAI-ARIA&lt;/a&gt; for some problems with it.&lt;/p&gt;
&lt;p&gt;The best solution for possessive nouns is to include the &amp;ldquo;apostrophe + s&amp;rdquo; inside the hyperlink.&lt;/p&gt;
&lt;h3 id=&#34;other-tips-for-screen-readers&#34;&gt;Other tips for screen readers&lt;/h3&gt;
&lt;p&gt;Designers already test their websites with multiple browser engines to ensure cross-browser compatibility. Screen readers deserve the same treatment. Orca, VoiceOver, NVDA, Narrator, JAWS, TalkBack, ChromeVox, KaiOS Readout, et al. all have unique behavior. In addition, different browsers&amp;mdash;even different Chromium forks&amp;mdash;expose content to screen readers differently. You&amp;rsquo;ll need to test multiple screen readers in multiple browsers, and keep track of updates to both. See why standards compliance is important?&lt;/p&gt;
&lt;p&gt;Screen readers on touch screen devices are also quite different from their desktop counterparts, and typically feature fewer capabilities. Be sure to test on both desktop and mobile.&lt;/p&gt;
&lt;p&gt;Screen reader implementations often skip punctuation marks like the exclamation point (&lt;samp&gt;!&lt;/samp&gt;). Ensure that meaning doesn&amp;rsquo;t rely too heavily on such punctuation.&lt;/p&gt;
&lt;p&gt;Screen readers have varying levels of verbosity. The default verbosity level doesn&amp;rsquo;t always convey inline emphasis, such as &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt;. Ensure that your meaning carries through without these semantics.&lt;sup id=&#34;fnref:37&#34;&gt;&lt;a href=&#34;#fn:37&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;37&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Default verbosity does, however, convey symbols and emoji. Use symbols and emoji judiciously, since they can get pretty noisy if you aren&amp;rsquo;t careful. Use &lt;code&gt;aria-labelledby&lt;/code&gt; on symbols when appropriate; I used labels to mark my footnote backlinks, which would otherwise be read as &lt;samp&gt;right arrow curving left&lt;/samp&gt;. If you have to use a symbol or emoji, first test how assistive technologies announce it; the emoji name may not communicate what you expect.&lt;/p&gt;
&lt;p&gt;Beware of &lt;code&gt;display&lt;/code&gt; and &lt;code&gt;visibility&lt;/code&gt; CSS properties; they can interfere with content reported to screen readers (see &lt;a href=&#34;#display-props&#34;&gt;quote from Steve Faulkner&lt;/a&gt;). Whenever you use one of those properties, re-test with screen readers just to be safe.&lt;/p&gt;
&lt;figure id=&#34;display-props&#34; tabindex=&#34;-1&#34;&gt;
&lt;blockquote&gt;
&lt;p&gt;Sometimes [using &lt;code&gt;display&lt;/code&gt; properties] can have an unintended effect of nuking the semantics of the elements, as conveyed to screen reading software, in the &lt;a href=&#34;https://www.tpgi.com/the-browser-accessibility-tree/&#34;&gt;browser accessibility tree&lt;/a&gt;. Screen readers and other assistive tech, in general, do not have direct access to the HTML DOM, they are provided access to a subset of information in the HTML DOM via &lt;a href=&#34;https://www.w3.org/TR/wai-aria-1.1/#dfn-accessibility-api&#34;&gt;Accessibility APIs&lt;/a&gt;. Sometimes what an element represents in the HTML DOM is not how it is represented in the accessibility tree.&lt;/p&gt;
&lt;p&gt;If what is represented in the accessibility tree does not represent the developer’s intended UI, it’s either (wittingly / unwittingly) the &lt;strong&gt;fault of the developer or the browser&lt;/strong&gt;. But what we can be sure of, in these cases, is that it is &lt;strong&gt;not the fault of the screen reader&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://twitter.com/stevefaulkner&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Steve&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Faulkner&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
from &lt;span class=&#34;p-org org&#34;&gt;
&lt;a class=&#34;organization-name&#34; href=&#34;https://www.tpgi.com/&#34;&gt;
&lt;span&gt;TPGi&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.tpgi.com/short-note-on-what-css-display-properties-do-to-table-semantics/&#34;&gt;Short note on what CSS display properties do to table semantics&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h2 id=&#34;future-users&#34;&gt;Future users&lt;/h2&gt;
&lt;p&gt;The number of people using your site in the future is hopefully greater than the number of people using your site in the present. Accordingly, your pages need to work correctly in the future.&lt;/p&gt;
&lt;p&gt;Much of this section borrows from the article &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://jeffhuang.com/designed_to_last/&#34;&gt;This Page is Designed to Last&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;; I highly recommend giving it a read.&lt;/p&gt;
&lt;h3 id=&#34;third-parties&#34;&gt;Third parties&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve already made a privacy and performance case against third-party resources in an earlier &lt;a href=&#34;#third-party-content&#34;&gt;&amp;ldquo;Third-party content&amp;rdquo; subsection&lt;/a&gt;. Another reason to avoid third-party resources is longevity. Third-party scripts, styles, frames, and images all depend on someone else&amp;rsquo;s host keeping the resource available at the same URL; over time, these tend to disappear. Sticking to first-party content reduces these points of failure.&lt;/p&gt;
&lt;p&gt;Third-party content is especially problematic when it&amp;rsquo;s hosted on modest hardware. If your site &amp;ldquo;goes viral&amp;rdquo;, your traffic could take down the third-party site or prompt them to disable hotlinking. &lt;em&gt;Serve assets yourself.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;dead-links&#34;&gt;Dead links&lt;/h3&gt;
&lt;p&gt;On the same note: your internal and external &lt;a href=&#34;https://en.wikipedia.org/wiki/Link_rot&#34;&gt;links to other pages need to change with time&lt;/a&gt;. Use a broken-link checker regularly to ensure that your content stays alive. I recommend checkers like &lt;a href=&#34;https://github.com/lycheeverse/lychee&#34;&gt;lychee&lt;/a&gt; and &lt;a href=&#34;https://github.com/wjdp/htmltest&#34;&gt;htmltest&lt;/a&gt; because they can cache results. My site has a bit under two thousand links at the time of writing; checking all of them at once would be exhausting, but using a week-long cache allows me to split this over seven days.&lt;/p&gt;
&lt;p&gt;Whenever you link to a page, try to archive a snapshot of it. &lt;a href=&#34;https://web.archive.org/&#34;&gt;The Wayback Machine&lt;/a&gt;, &lt;a href=&#34;https://archive.today/&#34;&gt;archive.today&lt;/a&gt;, and &lt;a href=&#34;https://ghostarchive.org/&#34;&gt;Ghostarchive&lt;/a&gt; are popular options. Archival is one of the few times I recommend using a third-party service; a service like the Wayback Machine will likely outlive your website. That being said, &lt;a href=&#34;https://archivebox.io/&#34;&gt;self-hosted solutions like ArchiveBox&lt;/a&gt; do exist.&lt;/p&gt;
&lt;p&gt;If you link often enough, archival might be something worth automating. The Wayback Machine offers an API, and allows registered users to mass-archive archive all outlinks in a page.&lt;/p&gt;
&lt;h3 id=&#34;reproducibility&#34;&gt;Reproducibility&lt;/h3&gt;
&lt;p&gt;Imagine your typical &amp;ldquo;modern&amp;rdquo; website&amp;rsquo;s deployment pipeline. It requires thousands of dependencies to build. It uses bespoke tools to deploy to a service provider with a custom non-standard stack (e.g. Fly.io, Heroku, Cloudflare Workers, AWS Lambda).&lt;/p&gt;
&lt;p&gt;Ten years from now, how much of this will still work?&lt;/p&gt;
&lt;p&gt;Try to ensure that your website can be archived, and/or easily re-built and served on an ordinary server. This way, your work can still be made accessible after you&amp;rsquo;re gone. For example: all my site requires to build is a tarball of statically-linked binaries, a POSIX shell, and a decent Make implementation (bmake and GNU make work) to build; see &lt;a href=&#34;https://git.sr.ht/~seirdy/seirdy.one/tree/e591c9d1ee54c16c40f4b8f2c1eab9e830577681/item/.build.yml&#34;&gt;my build manifest&lt;/a&gt;. To serve, it just needs a static web server.&lt;/p&gt;
&lt;h2 id=&#34;testing&#34;&gt;Testing&lt;/h2&gt;
&lt;p&gt;If your site is simple enough, it should automatically handle the vast majority of edge-cases. Different devices and browsers all have their quirks, but they generally have one thing in common: they understand &lt;abbr title=&#34;Plain-Old, Semantic HTML&#34;&gt;POSH&lt;/abbr&gt;.&lt;/p&gt;
&lt;p&gt;No matter how simple a page is, I don&amp;rsquo;t think simplicity eliminates the need for testing. I outlined the need to analyze actual run-time behavior in &lt;a href=&#34;https://envs.net/~seirdy/2022/02/02/floss-security/&#34;&gt;another post exploring how code alone doesn&amp;rsquo;t give the full picture&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;automated-tests&#34;&gt;Automated tests&lt;/h3&gt;
&lt;p&gt;Automated tests&amp;mdash;especially accessibility tests&amp;mdash;are a supplement to manual tests, not a replacement for them. Think of them as time-savers that bring up issues for further research, containing both false positives and false negatives.&lt;/p&gt;
&lt;p&gt;These are the tools I use regularly. I&amp;rsquo;ve deliberately excluded tools that would be redundant.&lt;sup id=&#34;fnref:38&#34;&gt;&lt;a href=&#34;#fn:38&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;38&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&#34;https://validator.nu/&#34;&gt;Nu HTML checker&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The W3C&amp;rsquo;s official HTML validator. Valid HTML ensures broader compatibility with a wider range of agents. Note that it uses Jigsaw under the hood for CSS validation, which hasn&amp;rsquo;t implemented support for certain CSS features I&amp;rsquo;ve recommended elsewhere on this page. Watch out for false positives.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://github.com/dequelabs/axe-core&#34;&gt;axe-core&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;The current standard in accessibility testing. Most website auditors that run accessibility checks use this library under the hood.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://developers.google.com/web/tools/lighthouse/&#34;&gt;&lt;span id=&#34;lighthouse&#34;&gt;Lighthouse&lt;/span&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;An auditing tool by Google that uses the DevTools protocol in any Chromium-based browser. Skip the &amp;ldquo;Access­ibility&amp;rdquo; category, since it just runs a subset of axe-core&amp;rsquo;s audits. The most useful audit is the tap target size check in its &amp;ldquo;SEO&amp;rdquo; category. It&amp;rsquo;s also convenient for measuring performance with CPU throttling, to simulate low-end mobile devices. Note that your &lt;code&gt;sandbox&lt;/code&gt; CSP directive will need to include &lt;code&gt;allow-scripts&lt;/code&gt; for it to function.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://webhint.io/&#34;&gt;Webhint&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Similar to Lighthouse. Again, you can ignore the accessibility audits if you already use axe-core. I personally disagree with some of its hints: the &amp;ldquo;unneeded HTTP headers&amp;rdquo; hint ignores the fact that the CSP can have an effect on non-hypertext assets, the &amp;ldquo;HTTP cache&amp;rdquo; hint has an unreasonable bias against caching HTML, and the &amp;ldquo;Correct &lt;code&gt;Content-Type&lt;/code&gt; header&amp;rdquo; recommends charset attributes a bit too agg­ressively.&lt;sup id=&#34;fnref:39&#34;&gt;&lt;a href=&#34;#fn:39&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;39&lt;/a&gt;&lt;/sup&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://www.ibm.com/able/toolkit/verify/automated/&#34;&gt;IBM Equal Access Accessibility Checker&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Has a scope similar to axe-core. Its &amp;ldquo;Sensory Characteristics&amp;rdquo; audit seems unique.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://ainspector.disability.illinois.edu/&#34;&gt;AInspector&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;A Firefox addon that displays audits in the sidebar. In my experience, it does have many false-positives (especially regarding DPUB-ARIA; see &lt;a href=&#34;https://github.com/opena11y/evaluation-library/issues/3&#34;&gt;issue 3 for the OpenA11y Evaluation Library&lt;/a&gt;); however, it has caught a few issues missed by all other tools.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://firefox-source-docs.mozilla.org/devtools-user/accessibility_inspector/index.html#check-for-accessibility-issues&#34;&gt;Firefox&amp;rsquo;s Accessibility Inspector&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Supports some very basic audits for contrast, keyboard access, and text labels. The accessibility tree is also a useful way to ensure that elements have accessible names. The keyboard audits have false-positives on non-interactive elements with scrollable overflow, which need to be focusable.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://developer.chrome.com/docs/devtools/css-overview/&#34;&gt;Chromium&amp;rsquo;s CSS Overview&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Can show some basic accessibility violations, including contrast violations. I recommend enabling the APCA-based contrast algorithm in the DevTools experimental settings first. Note that this uses an earlier version of APCA and does not account for contrast that is too high.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://testssl.sh/&#34;&gt;testssl.sh (cli)&lt;/a&gt; OR &lt;a href=&#34;https://www.ssllabs.com/ssltest/&#34;&gt;SSL Labs&amp;rsquo; SSL Server Test (web, proprietary)&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Basically equivalent tools for auditing your TLS setup. I prefer testssl.sh.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://webbkoll.dataskydd.net/&#34;&gt;Webbkoll&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Basic security checks, focusing on HTTP headers. I consider it a spiritual successor to Mozilla&amp;rsquo;s HTTP Observatory.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://check-your-website.server-daten.de/&#34;&gt;Check Your Website&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Slower, more in-depth website checks with an emphasis on security. It covers name server configurations, DNSSEC, DANE, email DNS records, MTA-STS, well-known paths, redirects, certificate transparency, subresource integrity, caching, and well-known ports.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&#34;https://internet.nl/&#34;&gt;Internet.nl&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Possibly the harshest website security and modernity check on this list, and my personal favorite. Checks for IPv6 reachability, modern cipher suites and key-exchange params, DNSSEC, and &lt;abbr&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Resource_Public_Key_Infrastructure&#34;&gt;RPKI&lt;/a&gt;&lt;/abbr&gt;. It also has handy tools to check an email server, and your own personal connection.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;unorthodox-tests&#34;&gt;Unorthodox tests&lt;/h3&gt;
&lt;p&gt;In addition to standard testing, I recommend testing with unorthodox setups that are unlikely to be found in the wild. If a website doesn&amp;rsquo;t work well in one of these tests, there&amp;rsquo;s a good chance that it uses an advanced Web feature that can serve as a point of failure in other cases. Simple sites should be able to look good in a variety of situations out of the box.&lt;/p&gt;
&lt;p&gt;Your page should easily pass the harshest of tests without any extra effort if its HTML meets basic standards for well-written code (overlooking bad formatting and a lack of comments). Even if you use a complex static site generator, the final HTML should be simple, readable, and semantic.&lt;/p&gt;
&lt;p&gt;These tests begin reasonably, but gradually grow absurd. Once again, use your judgement.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Test in all three major browser engines: Blink, Gecko, and WebKit.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Evaluate the heaviness and complexity of your scripts (if any) by testing with your browser&amp;rsquo;s &lt;abbr title=&#34;just-in-time&#34;&gt;JIT&lt;/abbr&gt; compilation disabled.&lt;sup id=&#34;fnref:40&#34;&gt;&lt;a href=&#34;#fn:40&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;40&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test using the Tor Browser&amp;rsquo;s safest security level enabled (disables JS and other features).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Load just the HTML. No CSS, no images, etc. Try loading without inline CSS as well for good measure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Print some pages in black-and-white, preferably with a simple laser printer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test with assistive technologies such as screen readers, magnifiers, and switch controls.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure the page responds correctly to browser zoom. No sizes or dimensions should remain &amp;ldquo;fixed&amp;rdquo; across zoom levels.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test keyboard navigability with the &lt;kbd&gt;Tab&lt;/kbd&gt; key and caret navigation. Even without specifying tab indexes, tab selection should follow a logical order if you keep the layout simple.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test in textual browsers: lynx, links, w3m, ELinks, edbrowse, EWW, Netrik, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test in an online website translator tool.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test your feeds (RSS, Atom, JSON, etc.) in multiple readers to ensure they render your markup correctly. Microsoft Outlook uses Word&amp;rsquo;s Internet-Explorer-based HTML engine to display these contents; Newsboat uses its own custom HTML renderer. Most don&amp;rsquo;t support CSS.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read the (prettified and indented) HTML source itself and parse it with your brain. See if anything seems illogical or unnecessary. Imagine giving someone a printout of your page&amp;rsquo;s &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; along with a whiteboard. If they have a basic knowledge of HTML tags, would they be able to draw something resembling your website?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test with unorthodox graphical browser engines, like NetSurf, Dillo, Servo, or the Serenity OS browser.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test how your page renders in ancient browsers, like Netscape Navigator or Tkhtml. Use a TLS terminator or serve over HTTP from localhost.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Try printing out your page in black-and-white from an unorthodox graphical browser.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download your webpage and test how multiple word processors render and generate PDFs from it.&lt;sup id=&#34;fnref:41&#34;&gt;&lt;a href=&#34;#fn:41&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;41&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Combine conversion tools. Combine an HTML-&lt;wbr /&gt;to-&lt;wbr /&gt;EPUB converter and an EPUB-&lt;wbr /&gt;to-&lt;wbr /&gt;PDF converter, or stack multiple article-extraction utilities. Be creative and enjoy breaking your site. When something breaks, examine the breakage and see if it&amp;rsquo;s caused by an issue in your markup, or a CSS feature with an equivalent alternative.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build a time machine. Travel decades&amp;mdash;or perhaps centuries&amp;mdash;into the future. Keep going forward until the WWW is breathing its last breath. Test your site on future browsers. Figuring out how to transfer your files onto their computers might take some time, but you have a time machine so that shouldn&amp;rsquo;t be too hard. When you finish, go back in time to &lt;a href=&#34;https://xkcd.com/567/&#34;&gt;meet Benjamin Franklin&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;m still on step 17, trying to find new ways to break this page. If you come up with a new test, please &lt;a href=&#34;mailto:~seirdy/seirdy.one-comments@lists.sr.ht&#34;&gt;share it&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;

&lt;p&gt;&lt;picture&gt;&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/serenity_dark.1026025796.webp&#34;
type=&#34;image/webp&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/serenity_dark.312494276.png&#34;
type=&#34;image/png&#34;
media=&#34;screen and (prefers-color-scheme: dark)&#34; /&gt;
&lt;source
srcset=&#34;https://envs.net/~seirdy/~seirdy/p/serenity.2860217767.png&#34;
type=&#34;image/png&#34; /&gt;
&lt;img class=&#34;pix&#34;
width=&#34;334&#34; height=&#34;572&#34;
src=&#34;https://envs.net/~seirdy/p/serenity.2860217767.png&#34; alt=&#34;Retro-looking browser with bitmap fonts showing this article’s “code snippet 4”.&#34;

decoding=&#34;async&#34; /&gt;
&lt;/picture&gt;&lt;/p&gt;
&lt;figcaption&gt;
&lt;p&gt;This page in the &lt;a href=&#34;https://serenityos.org/&#34;&gt;SerenityOS&lt;/a&gt; web browser. TLS 1.2 support isn&amp;rsquo;t finished yet; I loaded it from a mirror with a compatible cipher suite.&lt;/p&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;h2 id=&#34;future-updates&#34;&gt;Future updates&lt;/h2&gt;
&lt;p&gt;This article is, and will probably always be, an ongoing work-in-progress. Some areas I have yet to cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How purely-cosmetic animations harm readers with learning and cognitive disabilities (e.g. attention disorders).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How exposing new content on hover is inaccessible to users with magnifiers, hand tremors, switch access, and touchscreens.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Notes on improving support for braille displays.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to work well with caret-based navigation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to choose phrasings such that some meaning can be inferred without understanding numbers, for &lt;a href=&#34;https://en.wikipedia.org/wiki/Dyscalculia&#34;&gt;dyscalculic readers&lt;/a&gt;. This is more applicable to posts whose main focus is not mathematical or quantitative.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to include mathematical notation in a way that maximizes compatibility and accessibility.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keypad-based navigation on feature phones (c.f. KaiOS devices).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How keyboard navigation can be altered by assistive tools such as screen readers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to avoid relying too much on formatting, for user agents that display unformatted text (e.g. textual feed readers like Newsboat)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Elaboration on how authors should delegate much of their formatting to the user agent, and how CSS resets are a symptom of a failure to do so.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keyboard-driven browsers and extensions. Qutebrowser, Luakit, visurf, Tridactyl, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ways to support non-mainstream and older browsers by supporting subsets of specifications and using progressive enhancement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoiding &lt;code&gt;_blank&lt;/code&gt; targets in URLs unless absolutely necessary.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ways to improve comprehension by readers who struggle to understand non-literal language (certain cognitive disabilities, non-native speakers unfamiliar with idioms, etc.). I might wait until the &lt;cite&gt;&lt;a href=&#34;https://www.w3.org/TR/adapt-help/&#34;&gt;WAI-Adapt: Help and Support Module&lt;/a&gt;&lt;/cite&gt; draft specification matures and its vocabularies gain adoption before going in depth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spatial navigation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&#34;https://w3c.github.io/Mobile-A11y-TF-Note/#provide-clear-indication-that-elements-are-actionable&#34;&gt;principle of redundant coding&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Other accessible writing tips, maybe after I get a copy of &lt;span class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://rosenfeldmedia.com/books/writing-is-designing/&#34;&gt;Writing Is Designing&lt;/a&gt;&lt;/cite&gt; by &lt;span
	
	class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://mjmetts.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Michael&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Metts&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span
	
	class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.andy.wtf/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Andy&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Welfe&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;. A relevant excerpt on writing accessibly is &lt;a href=&#34;https://alistapart.com/article/standards-for-writing-accessibly/&#34;&gt;on A List Apart&lt;/a&gt;.&lt;!--Hugo does something weird when I use my mention-work shortcode here.--&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rules for descriptive link text, for screen reader navigation and for user-agents that display links as footnotes (e.g. some textual browsers with the &lt;code&gt;dump&lt;/code&gt; flag).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There are so many ways to read a page; authors typically cater only to the mainstream ones. Some ways to read a page I covered include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Screen readers&lt;/li&gt;
&lt;li&gt;Switch access&lt;/li&gt;
&lt;li&gt;Navigating with the &lt;kbd&gt;Tab&lt;/kbd&gt; key&lt;/li&gt;
&lt;li&gt;Caret navigation&lt;/li&gt;
&lt;li&gt;Navigating with hand-tremors&lt;/li&gt;
&lt;li&gt;Content extractors or &amp;ldquo;Reader Mode&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Low-bandwidth connections&lt;/li&gt;
&lt;li&gt;Unreliable, lossy connections&lt;/li&gt;
&lt;li&gt;Metered connections&lt;/li&gt;
&lt;li&gt;Hostile networks&lt;/li&gt;
&lt;li&gt;Using in-page search&lt;/li&gt;
&lt;li&gt;Downloading offline copies&lt;/li&gt;
&lt;li&gt;Extra-narrow viewports&lt;/li&gt;
&lt;li&gt;Mobile devices in landscape mode&lt;/li&gt;
&lt;li&gt;Frequent viewport-resizers&lt;/li&gt;
&lt;li&gt;Printouts with rationed paper or ink&lt;/li&gt;
&lt;li&gt;Textual browsers&lt;/li&gt;
&lt;li&gt;Disabling JavaScript&lt;/li&gt;
&lt;li&gt;The Tor Browser&amp;rsquo;s &amp;ldquo;Safest&amp;rdquo; mode&lt;/li&gt;
&lt;li&gt;Non-mainstream browser engines&lt;/li&gt;
&lt;li&gt;Browsing without CSS&lt;/li&gt;
&lt;li&gt;Altering, injecting, or replacing CSS&lt;/li&gt;
&lt;li&gt;Non-default color palettes&lt;/li&gt;
&lt;li&gt;Forced color palettes&lt;/li&gt;
&lt;li&gt;Adblockers, with various filter-lists&lt;/li&gt;
&lt;li&gt;Blocking third-parties&lt;/li&gt;
&lt;li&gt;Disabling frames, images, and cookies&lt;/li&gt;
&lt;li&gt;User-selected custom fonts&lt;/li&gt;
&lt;li&gt;Machine translators&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these may be dismissed as a &amp;ldquo;niche&amp;rdquo;, especially given a profit motive (or worse, a growth imperative). Yet &lt;em&gt;many niches add up to a large population.&lt;/em&gt; Every person who grows old becomes disabled; every long-distance traveller experiences poor connections.&lt;/p&gt;
&lt;p&gt;Moreover, I don&amp;rsquo;t think that the size of a disadvantaged population should always matter. I understand weighing population size if you have to make a trade-off between two conflicting special needs, but I don&amp;rsquo;t think the aesthetic preferences of the majority are more important than supporting a disadvantaged minority.&lt;/p&gt;
&lt;p&gt;Before you throw up your hands and decide you can&amp;rsquo;t help everyone, take another skim through this page. Notice how much repetition exists between sections. &lt;em&gt;Nearly every bullet-point I listed benefits tremendously from plain-old, semantic HTML (&lt;abbr title=&#34;Plain-Old, Semantic HTML&#34;&gt;POSH&lt;/abbr&gt;)&lt;/em&gt;. If your page is usable with nothing but POSH, you&amp;rsquo;ve done half the work already.&lt;/p&gt;
&lt;section role=&#34;doc-acknowledgments&#34;&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Ack­nowledge­ments and further reading&lt;/h2&gt;
&lt;p&gt;Initial versions of this page were inspired by existing advocates for web minimalism.&lt;/p&gt;
&lt;p&gt;Parts of this page can be thought of as an extension to David Copeland&amp;rsquo;s principles of Brutalist Web Design.&lt;/p&gt;
&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;Raw content true to its construction:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Content is readable on all reasonable screens and devices.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Only hyperlinks and buttons respond to clicks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hyperlinks are underlined and buttons look like buttons.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The back button works as expected.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;View content by scrolling.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Decoration when needed and no unrelated content.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perfor­mance is a feature.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;figcaption&gt;
		&amp;mdash;&lt;span class=&#34;h-cite&#34; role=&#34;doc-credit&#34;&gt;
	&lt;span&gt;&lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://naildrivin5.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;David&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Copeland&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;,
&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://brutalist-web.design/&#34;&gt;Brutalist Web Design&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/figcaption&gt;

&lt;/figure&gt;

&lt;p&gt;The &lt;a href=&#34;https://250kb.club/&#34;&gt;250kb club&lt;/a&gt; gathers websites at or under 250kb, and also rewards websites that have a high ratio of content size to total size.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://web.archive.org/web/20231208000921/https://10kbclub.com/&#34;&gt;10KB Club&lt;/a&gt; did the same with a 10kb homepage budget (excluding favicons and webmanifest icons). It also had guidelines for note­worthiness, to avoid low-hanging fruit like mostly-blank pages.&lt;/p&gt;
&lt;p&gt;My favorite website club has to be the &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://xhtml.club/&#34;&gt;XHTML Club&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://bt.ht/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Bradley&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Taunt&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;, the creator of the original &lt;a href=&#34;https://1mb.club&#34;&gt;1mb.club&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also see &lt;a href=&#34;https://motherfuckingwebsite.com/&#34;&gt;Motherfucking Website&lt;/a&gt;. Motherfucking Website inspired several unofficial sequels that tried to gently improve upon it. My favorite is &lt;a href=&#34;https://bestmotherfucking.website/&#34;&gt;Best Motherfucking Website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.webbloatscore.com/&#34;&gt;Web Bloat Score calculator&lt;/a&gt; is a JavaScript app that compares a page&amp;rsquo;s size with the size of a PNG screenshot of the full page content, encouraging site owners to minimize the ratio of the two.&lt;/p&gt;
&lt;p&gt;One resource I found useful (that eventually featured this article!) was the &amp;ldquo;Your page content&amp;rdquo; section of &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.billdietrich.me/YourPersonalWebSite.html&#34;&gt;Your Personal Website&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.billdietrich.me&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Bill&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Dietrich&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve got some time on your hands, I &lt;em&gt;highly&lt;/em&gt; recommend reading the &lt;cite&gt;&lt;a href=&#34;https://www.w3.org/TR/WCAG22/&#34;&gt;Web Content Accessibility Guidelines (WCAG) 2.2&lt;/a&gt;&lt;/cite&gt;. The WCAG 2 standard is technology-neutral, so it doesn&amp;rsquo;t contain Web-specific advice. For that, check the &lt;cite&gt;&lt;a href=&#34;https://www.w3.org/WAI/WCAG22/quickref/&#34;&gt;How to Meet WCAG (Quick Reference)&lt;/a&gt;&lt;/cite&gt;. It combines the WCAG with its supplementary &lt;a href=&#34;https://www.w3.org/WAI/WCAG22/Techniques/&#34;&gt;list of techniques&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The WCAG are an excellent starting point for learning about accessibility, but make for a poor stopping point. Much of the content on this page simply isn&amp;rsquo;t covered by the WCAG. One of my favorite resources for learning about what the WCAG &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; cover is &lt;a href=&#34;https://axesslab.com/articles/&#34;&gt;Axess Lab&amp;rsquo;s articles&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve learned about a great number of under­represented ways to browse from the Fediverse, particularly from &lt;a href=&#34;https://pleroma.envs.net/notice/AHqp3TEDFoyz0W4nbc&#34;&gt;this subthread asking people to share&lt;/a&gt; (requires JavaScript; &lt;a href=&#34;https://gopher.envs.net/pleroma.envs.net:7070/1/notices/AHqp3TEDFoyz0W4nbc&#34;&gt;plaintext mirror&lt;/a&gt;). Several responses informed updates to this page.&lt;/p&gt;
&lt;p&gt;An early version of this article received useful responses when I &lt;a href=&#34;https://lobste.rs/s/akcw1m/opinionated_list_best_practices_for&#34;&gt;posted it to Lobsters&lt;/a&gt;; I incorporated some feedback shortly afterward.&lt;/p&gt;
&lt;p&gt;A special thanks goes out to GothAlice for the questions she answered in &lt;samp&gt;#webdev&lt;/samp&gt; on Libera.Chat.&lt;/p&gt;
&lt;/section&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Many addons function by injecting content into pages; this significantly weakens many aspects of the browser security model (e.g. site and origin isolation) and should be avoided if at all possible. For content such as public key fingerprints, I recommend setting a blank &lt;code&gt;sandbox&lt;/code&gt; directive even if it means breaking these addons.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Some addons will have reduced functionality; for instance, &lt;a href=&#34;https://github.com/tridactyl/tridactyl&#34;&gt;Tridactyl&lt;/a&gt; can&amp;rsquo;t create an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; for its command window. I consider this to be worthwhile since the most important functionality is still available, and because authors shouldn&amp;rsquo;t feel compelled to support security weakening. I say this as someone who uses Tridactyl often.&lt;/p&gt;
&lt;p&gt;Moreover, the &lt;code&gt;sandbox&lt;/code&gt; directive exposes some bugs in WebKit (i.e. Safari and most GTK-based browsers). On content governed by a &lt;code&gt;sandbox&lt;/code&gt; directive without the &lt;code&gt;allow-same origin&lt;/code&gt; and &lt;code&gt;allow-scripts&lt;/code&gt; directives, some WebKit browser features won&amp;rsquo;t work. One example is media controls. One page on my site has an &lt;code&gt;audio&lt;/code&gt; element; I added &lt;code&gt;allow-scripts&lt;/code&gt; to that page so it will work in WebKit-based browsers. &lt;a href=&#34;https://bugs.webkit.org/show_bug.cgi?id=237281&#34;&gt;WebKit bug 237281 documents the general issue&lt;/a&gt;; &lt;a href=&#34;https://bugs.webkit.org/show_bug.cgi?id=225865&#34;&gt;WebKit bug 225865&lt;/a&gt; and &lt;a href=&#34;https://bugs.webkit.org/show_bug.cgi?id=218086&#34;&gt;WebKit bug 218086&lt;/a&gt; document specific instances.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Here&amp;rsquo;s an &lt;a href=&#34;https://en.wikipedia.org/wiki/Progressive_enhancement&#34;&gt;overview of PE&lt;/a&gt; and &lt;a href=&#34;https://web.archive.org/web/20220316060312/https://whalecoiner.com/articles/progressive-enhancement&#34;&gt;my favorite write-up on the subject&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Each of these flows can be visually displayed using a breadcrumbs list; doing so can meet the WCAG &lt;a href=&#34;https://w3c.github.io/wcag/understanding/location.html&#34;&gt;Success Criterion 2.4.8: Location&lt;/a&gt;. I opted to meet the criterion a different way. Since all my pages are linked by my site&amp;rsquo;s global navigation or my &amp;ldquo;posts&amp;rdquo; page (also in the global navigation), I just used &lt;code&gt;aria-current&lt;/code&gt; and made the currently-relevant entry in my global navigation a &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; element. However, I later introduced breadcrumbs anyway because I don&amp;rsquo;t think a simple &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; element conveys this information clearly enough.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;One example is a utility class for the &lt;code&gt;image-rendering&lt;/code&gt; property. I use it on images that look better with &lt;code&gt;pixelated&lt;/code&gt; rendering. This is a property of the image contents, not the image semantics or placement; a class makes sense.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Technically, this is only true in idealized circumstances and if you have 0-RTT enabled. If your requests are not idempotent, you probably should stick with 1-RTT. A TCP handshake actually involves one additional round-trip, so you could probably start off with a 30-kilobyte window on HTTP/2 with 0-RTT. HTTP/3 servers with 0-RTT do use a true &amp;ldquo;zero-round-trip&amp;rdquo; connection, but they use QUIC instead of TCP. QUIC uses similar sizing logic but I&amp;rsquo;m not sure about the exact values.&lt;/p&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://hpbn.co/building-blocks-of-tcp/&#34;&gt;High-Performance Browser Networking&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.igvita.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Ilya&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Grigorik&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; gives a great introduction to how TCP works, if you&amp;rsquo;d like more details.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;This one-kilobyte limit is a semi-arbitrary rule-of-thumb I came up with. It&amp;rsquo;s a simple number easier to work with than the number of bytes remaining in the earliest contentful round-trip, yet it typically falls within that quota.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;HPACK and QPACK header compression includes dictionaries containing common header names, and some common header values; HPACK lists them in &amp;ldquo;Appendix A&amp;rdquo; of &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://datatracker.ietf.org/doc/html/rfc7541#appendix-A&#34;&gt;RFC 7541&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. If these dictionaries contain a given header name or name-value pair, the header name/value&amp;rsquo;s effective size can be reduced to a single byte. If a header has a value that isn&amp;rsquo;t covered by the table, consider minifying it by removing unnecessary whitespace.&lt;/p&gt;
&lt;p&gt;Remember that if your golden first kilobyte already lists all essential resources, these could be considered premature optimizations. Real bottlenecks lie elsewhere.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;Ironically, that page doesn&amp;rsquo;t load the main text without JavaScript despite citing a JavaScript requirement as a downside. If you can&amp;rsquo;t load the page, the same issues with infinte scroll are outlined in the &amp;ldquo;Accessibility concerns for infinite scroll&amp;rdquo; section of &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://addyosmani.com/blog/infinite-scroll-without-layout-shifts/&#34;&gt;Infinite Scroll without Layout Shifts&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://addyosmani.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Addy&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Osmani&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;The benefits of containment are especially noticeable when injecting styles into a page. &amp;ldquo;Dark mode&amp;rdquo; and &amp;ldquo;userstyle&amp;rdquo; extensions perform noticeably better when enough elements receive layout and paint containment. Containment allows browsers to handle changes to an element independently of the rest of the DOM.&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;&lt;a href=&#34;#lighthouse&#34;&gt;See the &amp;ldquo;Lighthouse&amp;rdquo; entry in the &amp;ldquo;Automated tests&amp;rdquo; section&lt;/a&gt;. Lighthouse benchmarks my machine with a score of around 1320; with that score, it recommends &lt;a href=&#34;https://github.com/patrickhulce/lighthouse-cpu-throttling-calculator/blob/a9c67dc1c58c972a0673bef05756290105334af1/pages/index.js#L11&#34;&gt;throttling my machine by just under 3.1x&lt;/a&gt; to simulate a target mobile device. The Chromium team came up with the throttling formula under idealized conditions (the phone isn&amp;rsquo;t overheating, battery-saver mode is off, etc); I go further and throttle between 12x and 13x, still shooting for a perfect performance score. This article is the largest page on my site; it often gets a perfect performance score (100) with my stylesheet enabled, but never reaches 100 when I disable CSS containment or remove my stylesheet.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;Version 12.0 of the Tor Browser was a rebase from Firefox 91.x &lt;abbr title=&#34;Extended Support Release&#34;&gt;ESR&lt;/abbr&gt; to Firefox 102.x &lt;abbr&gt;ESR&lt;/abbr&gt;. It was released more than &lt;a href=&#34;https://envs.net/~seirdy/~seirdy//~seirdy/notes/2022/09/19/state-of-the-tor-uplift/&#34;&gt;two months after Firefox 91.x &lt;abbr&gt;ESR&lt;/abbr&gt; reached End Of Life&lt;/a&gt;, almost &lt;a href=&#34;https://wiki.mozilla.org/Release_Management/Calendar&#34;&gt;16 months after Firefox 102.0 was initially released&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;KaiOS is the third most popular mobile OS, after Android and iOS; &lt;a href=&#34;https://economictimes.indiatimes.com/tech/software/after-mauling-telcos-mukesh-ambani-now-fires-at-operating-systems/articleshow/64958877.cms&#34;&gt;it&amp;rsquo;s the second-most popular mobile OS in India&lt;/a&gt;. Firefox updates are tied to operating-system updates in KaiOS. Since most manufacturers don&amp;rsquo;t support KaiOS devices for long (they&amp;rsquo;re budget feature phones for emerging markets), don&amp;rsquo;t expect KaiOS users to mass-upgrade their ancient Firefox versions anytime soon. The last KaiOS Firefox update was from version 49 to 84, almost one year after Firefox 84 came out.&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;The most recent such removal was the Document Outline algorithm. For years after it was standardized, &lt;a href=&#34;https://www.tpgi.com/html5-document-outline/&#34;&gt;the Document Outline was ignored by every browser engine&lt;/a&gt;. Finally, &lt;a href=&#34;https://github.com/whatwg/html/pull/7829&#34;&gt;the WHATWG replaced the Document Outline algorithm&lt;/a&gt; with a revised version that involved multiple heading levels. The revised version matches what user-agents and good authors have been doing for decades.&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://caniuse.com/ciu/about&#34;&gt;Can I Use is operated by a single person&lt;/a&gt;; check their site footer for donation information.&amp;#160;&lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34;&gt;
&lt;p&gt;There&amp;rsquo;s actually a surprising amount of overlap between iOS Lockdown mode and the Tor Browser&amp;rsquo;s security levels. Both disable WebGL, WebRTC, MathML, remote fonts, and JIT compilation. I recommend avoiding reliance features dangerous enough for privacy- and security-conscious users to disable.&amp;#160;&lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:17&#34;&gt;
&lt;p&gt;Firefox users &lt;a href=&#34;https://website-archive.mozilla.org/www.mozilla.org/access/access/type-ahead/&#34;&gt;can enable &amp;ldquo;find as you type&amp;rdquo;&lt;/a&gt; by toggling a preference in &lt;samp&gt;about:&lt;wbr /&gt;config&lt;/samp&gt;. Chromium (and derivatives) users can &lt;a href=&#34;https://github.com/Foxy/chrome-type-ahead&#34;&gt;install an extension like Type-ahead-find&lt;/a&gt;; note that it requires full-page access and performs script injection to work.&amp;#160;&lt;a href=&#34;#fnref:17&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:18&#34;&gt;
&lt;p&gt;Iterating through a list of font names to see if each one is available on a user&amp;rsquo;s system is a slow but effective way to determine installed fonts without being granted permission to use the Font Access API. &lt;a href=&#34;https://browserleaks.com/fonts&#34;&gt;Browser­Leaks has a demo&lt;/a&gt; of this approach. Warning: the page might hog your CPU for a while.&amp;#160;&lt;a href=&#34;#fnref:18&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:19&#34;&gt;
&lt;p&gt;Decoration is more than cosmetic. The &lt;a href=&#34;#color-overrides-and-accessibility&#34;&gt;color overrides and accessibility&lt;/a&gt; sub-section describes how some decorations, like borders, improve access­ibility.&amp;#160;&lt;a href=&#34;#fnref:19&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:20&#34;&gt;
&lt;p&gt;uBlock Origin is a popular browser extension for content filtering; it&amp;rsquo;s the most popular Firefox add-on. It includes a built-in feature to block all media elements exceeding a user-configurable size threshold.&amp;#160;&lt;a href=&#34;#fnref:20&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:21&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://wave.webaim.org/api/docs?format=html&#34;&gt;WebAIM&lt;/a&gt; and the &lt;a href=&#34;https://web.archive.org/web/20240310010822/https://fae.disability.illinois.edu/rulesets/IMAGE_4_EN/&#34;&gt;University of Illinois&lt;/a&gt; recommend 100 characters; &lt;a href=&#34;https://www.tanaguru.com/en/&#34;&gt;Tangaru&lt;/a&gt; recommends an even smaller limit of 80 characters. I sometimes exceed 100 characters for detailed images but usually stay below 80.&amp;#160;&lt;a href=&#34;#fnref:21&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:22&#34;&gt;
&lt;p&gt;Browser support for displaying alt-text in place of broken images seems good. More information about support for alt-text exposure can be found on &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://adrianroselli.com/2020/10/alternative-text-for-css-generated-content.html&#34;&gt;Alternative Text for CSS Generated Content&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt;. That post seems to indicate that Firefox 81 on macOS 10.15 didn&amp;rsquo;t display alt-text, but &lt;a href=&#34;https://web.archive.org/web/20231210072526/https://cybre.space/@nleigh/108688070682694730&#34;&gt;users report correct alt-text display&lt;/a&gt; in more recent Firefox versions.&amp;#160;&lt;a href=&#34;#fnref:22&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:23&#34;&gt;
&lt;p&gt;Once it gains basic support across all browsers and screen readers, I might recommend using &lt;code&gt;aria-details&lt;/code&gt; instead of &lt;code&gt;aria-&lt;wbr /&gt;describedby&lt;/code&gt; for more complex descriptions. At the time of writing, &lt;a href=&#34;https://a11ysupport.io/tech/aria/aria-details_attribute&#34;&gt;&lt;code&gt;aria-details&lt;/code&gt; is only supported by JAWS&lt;/a&gt;. &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.w3.org/TR/wai-aria-1.2/#aria-details&#34;&gt;WAI-ARIA 1.2&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; describes &lt;code&gt;aria-details&lt;/code&gt; with an example similar to the one I gave in &lt;a href=&#34;#xkcd-html&#34;&gt;code snippet 5&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:23&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:24&#34;&gt;
&lt;p&gt;Since &lt;abbr title=&#34;Windows High Contrast Mode&#34;&gt;WHCM&lt;/abbr&gt; sets colors independently of explicitly-defined ARIA roles, it&amp;rsquo;s a good way to test adherence to &lt;a href=&#34;#first-rule-of-aria&#34;&gt;the First Rule of ARIA&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:24&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:25&#34;&gt;
&lt;p&gt;An earlier version of this article recommended a background of &lt;code&gt;#111&lt;/code&gt;, but two helpful readers sensitive to overstimulation and halation found &lt;code&gt;#191919&lt;/code&gt; preferable.&amp;#160;&lt;a href=&#34;#fnref:25&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:26&#34;&gt;
&lt;p&gt;Lē also &lt;a href=&#34;https://web.archive.org/web/20230530094242/https://a11yrules.com/podcast/le-silveus-mcnamara-talks-about-neurodivergence-color-choices-and-overstimulation/&#34;&gt;shared their experience in A11y Rules&lt;/a&gt;, one of my favorite podcasts&amp;#160;&lt;a href=&#34;#fnref:26&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:27&#34;&gt;
&lt;p&gt;When making an earlier version of this site&amp;rsquo;s dark-mode color palette, I made the mistake of exclusively testing in cheap or poorly-calibrated displays with bright black points. I mistakenly thought that my &lt;code&gt;#0b0b0b&lt;/code&gt; background was bright enough to &lt;a href=&#34;#halation&#34;&gt;prevent halation&lt;/a&gt;. Only after testing on a better screen did I realize that it would look almost completely black; I subsequently lightened the background to &lt;code&gt;#111&lt;/code&gt; to strike a good balance.&amp;#160;&lt;a href=&#34;#fnref:27&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:28&#34;&gt;
&lt;p&gt;&lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://practicaltypography.com/&#34;&gt;Practical Typography&lt;/a&gt;&lt;/cite&gt;&lt;/span&gt; only renders invisible text without JavaScript. You can use a textual browser, screen reader, copy-paste the page contents elsewhere, use a reader-mode implementation, or &amp;ldquo;view source&amp;rdquo; to read it without enabling scripts. All of these options will ironically override the carefully-crafted typography of this website about typography.&lt;/p&gt;
&lt;p&gt;I find &lt;cite&gt;Practical Typography&lt;/cite&gt; quite useful for printed works, and incorporated a more moderate version of its advice on soft-hyphens into this page. With a few such exceptions, I generally find it to be poor advice for Web content.&amp;#160;&lt;a href=&#34;#fnref:28&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:29&#34;&gt;
&lt;p&gt;I can&amp;rsquo;t confirm if this is also an issue on VoiceOver for macOS, because I haven&amp;rsquo;t borrowed the hardware required to test it.&amp;#160;&lt;a href=&#34;#fnref:29&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:30&#34;&gt;
&lt;p&gt;I linked to a snapshot from the Wayback Machine in hopes that the live version of the Smashing Magazine site will get fixed.&amp;#160;&lt;a href=&#34;#fnref:30&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:31&#34;&gt;
&lt;p&gt;libavif links against libaom, librav1e, and/or libsvtav1 to perform AVIF encoding and decoding. libaom is best for this use-case, particularly since libaom can link against libjxl to use its Butteraugli distortion metric. This lets libaom optimize the perceptual quality of lossy encodes much more accurately.&amp;#160;&lt;a href=&#34;#fnref:31&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:32&#34;&gt;
&lt;p&gt;I find it quite odd that Microsoft Edge doesn&amp;rsquo;t support AVIF. Chromium has supported AVIF for a long time, and Edge is based on Chromium. AVIF is a royalty-free format; I don&amp;rsquo;t know why Microsoft would remove support for it, especially since Microsoft allows adding AVIF support to Windows. I think Edge also removed Chromium&amp;rsquo;s experimental, off-by-default support for JPEG-XL.&amp;#160;&lt;a href=&#34;#fnref:32&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:33&#34;&gt;
&lt;p&gt;I say that a skip link is useful to reduce the amount of &lt;kbd&gt;Tab&lt;/kbd&gt; keystrokes required, but I don&amp;rsquo;t know a good &amp;ldquo;threshold number&amp;rdquo; to signify &amp;ldquo;too many keystrokes&amp;rdquo;. If it takes ten keystrokes to reach the main content, it&amp;rsquo;s probably time to add a skip-link.&amp;#160;&lt;a href=&#34;#fnref:33&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:34&#34;&gt;
&lt;p&gt;ATs typically let users navigate by headings, landmarks, paragraphs, and links. Most users prefer skipping article content with heading-based navigation. Keyboard users can bind different keys to different modes of navigation, but mobile users can only access one navigation mode at a time.&lt;/p&gt;
&lt;p&gt;Mobile users wishing to temporarily switch modes have to stop, change their navigation mode, perform a navigation gesture, and switch back. Mobile users trying to skim an article don&amp;rsquo;t always find this worth the effort and sometimes stick to heading-based navigation even when a different mode would be optimal.&amp;#160;&lt;a href=&#34;#fnref:34&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:35&#34;&gt;
&lt;p&gt;At least, it will be until &lt;a href=&#34;https://github.com/nvaccess/nvda/issues/9343&#34;&gt;NVDA bug 9343&lt;/a&gt; gets resolved.&amp;#160;&lt;a href=&#34;#fnref:35&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:36&#34;&gt;
&lt;p&gt;If you&amp;rsquo;d like to learn more, &lt;span
	class=&#34;h-cite&#34;&gt;&lt;cite class=&#34;p-name&#34;&gt;&lt;a class=&#34;u-url&#34; href=&#34;https://www.sarasoueidan.com/blog/focus-indicators/&#34;&gt;A guide to designing accessible, WCAG-compliant focus indicators&lt;/a&gt;&lt;/cite&gt; by &lt;span

class=&#34;h-card vcard p-author&#34;&gt;&lt;a href=&#34;https://www.sarasoueidan.com/&#34; class=&#34;u-url url&#34;&gt;&lt;span class=&#34;p-name fn n&#34;&gt;&lt;span class=&#34;p-given-name given-name&#34;&gt;Sara&lt;/span&gt; &lt;span class=&#34;p-family-name family-name&#34;&gt;Soueidan&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt; has far more details on making accessible focus indicators.&amp;#160;&lt;a href=&#34;#fnref:36&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:37&#34;&gt;
&lt;p&gt;Screen readers aren&amp;rsquo;t alone here. Several programs strip inline formatting: certain feed readers, search result snippets, and textual browsers invoked with the &lt;code&gt;-dump&lt;/code&gt; flag are some examples I use every day.&amp;#160;&lt;a href=&#34;#fnref:37&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:38&#34;&gt;
&lt;p&gt;I excluded PageSpeed Insights and GTMetrix since those are mostly covered by Lighthouse. I excluded &lt;a href=&#34;https://hardenize.com/&#34;&gt;Hardenize&lt;/a&gt; and &lt;a href=&#34;https://cryptcheck.fr/&#34;&gt;CryptCheck&lt;/a&gt;, since their scope is covered by Internet.nl.&lt;/p&gt;
&lt;p&gt;I excluded Security Headers, since its approach seems to be recommending headers regardless of whether or not they are necessary. It penalizes forgoing the &lt;code&gt;Permissions-&lt;wbr /&gt;Policy&lt;/code&gt; header even if the CSP blocks script loading and execution; see &lt;a href=&#34;https://github.com/securityheaders/securityheaders-bugs/issues/103&#34;&gt;Security Headers issue #103&lt;/a&gt;. I personally find the &lt;code&gt;Permissions-&lt;wbr /&gt;Policy&lt;/code&gt; header quite problematic, as I noted in August 2021 on &lt;a href=&#34;https://github.com/w3c/webappsec-permissions-policy/issues/189#issuecomment-904783021&#34;&gt;webappsec-permissions-policy issue #189&lt;/a&gt;. Finally, Security Headers doesn&amp;rsquo;t have in-depth checks of the &lt;em&gt;values&lt;/em&gt; of headers; Internet.nl does a much better job of that. Security should be a thoughtful process, not a checklist.&amp;#160;&lt;a href=&#34;#fnref:38&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:39&#34;&gt;
&lt;p&gt;My site caches HTML and RSS feed for a few hours. I disagree with webhint&amp;rsquo;s recommendations against this: cache durations should be based on request rates and how often a resource is updated. I also disagree with some of its &lt;code&gt;content-type&lt;/code&gt; recommendations: you don&amp;rsquo;t need to declare UTF-8 charsets for SVG content-type headers if the SVG is ASCII-only and called from a UTF-8 HTML document. You gain nothing but header bloat by doing so.&amp;#160;&lt;a href=&#34;#fnref:39&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:40&#34;&gt;
&lt;p&gt;Consider disabling the JIT for your normal browsing too; doing so removes whole classes of vulnerabilities. In Firefox, navigate to &lt;samp&gt;about:&lt;wbr /&gt;config&lt;/samp&gt; and toggle some flags under &lt;code&gt;javascript&lt;wbr /&gt;.options&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;figcaption&gt;
&lt;strong id=&#34;code-snippet=12&#34;&gt; &lt;span&gt;Code snippet&lt;/span&gt; 12&lt;/strong&gt;:
    Firefox prefs to turn off JIT compilation
    &lt;/figcaption&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;javascript.options.ion
javascript.options.baselinejit
javascript.options.native_regexp
javascript.options.asmjs
javascript.options.wasm&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;In Chromium and derivatives, run the browser with &lt;code&gt;--js-flags=&#39;--jitless&#39;&lt;/code&gt;; in the Tor Browser, set the security level to &amp;ldquo;Safer&amp;rdquo;.&amp;#160;&lt;a href=&#34;#fnref:40&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:41&#34;&gt;
&lt;p&gt;LibreOffice can also render HTML but has extremely limited support for CSS. OnlyOffice seems to work best, but doesn&amp;rsquo;t load images. If your page is CSS-optional, it should look fine in both.&amp;#160;&lt;a href=&#34;#fnref:41&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item><title>Resilient Git, Part 1: Hydra Hosting</title>
      <link>https://envs.net/~seirdy/posts/2020/11/18/git-workflow-1/</link>
      <pubDate>Thu, 19 Nov 2020 02:31:15 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2020/11/18/git-workflow-1/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2020/11/18/git-workflow-1/">&lt;div role=&#34;note&#34;&gt;
&lt;p&gt;This is Part 1 of a series called &lt;a href=&#34;../../../../2020/11/17/git-workflow-0/&#34;&gt;Resilient Git&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;section role=&#34;doc-introduction&#34;&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Intro­duction&lt;/h2&gt;
&lt;p&gt;The most important part of a project is its code. Resilient projects should have their code in multiple places of equal weight so that work continues normally if a single remote goes down.&lt;/p&gt;
&lt;p&gt;Many projects already do something similar: they have one &amp;ldquo;primary&amp;rdquo; remote and several mirrors. I&amp;rsquo;m suggesting something different. Treating a remote as a &amp;ldquo;mirror&amp;rdquo; implies that the remote is a second-class citizen. Mirrors are often out of date and aren&amp;rsquo;t usually the preferred place to fetch code. Instead of setting up a primary remote and mirrors, I propose &lt;strong&gt;hydra hosting:&lt;/strong&gt; setting up multiple primary remotes of equal status and pushing to/fetching from them in parallel.&lt;/p&gt;
&lt;p&gt;Having multiple primary remotes of equal status might sound like a bad idea. If there are multiple remotes, how do people know which one to use? Where do they file bug reports, get code, or send patches? Do maintainers need to check multiple places?&lt;/p&gt;
&lt;p&gt;No. Of course not. A good distributed system should automatically keep its nodes in sync to avoid the hassle of checking multiple places for updates.&lt;/p&gt;
&lt;/section&gt;
&lt;h2 id=&#34;adding-remotes&#34;&gt;Adding remotes&lt;/h2&gt;
&lt;p&gt;This process should pretty straightforward. You can run &lt;code&gt;git remote add&lt;/code&gt; (see &lt;code&gt;git-remote(1)&lt;/code&gt;) or edit your repo&amp;rsquo;s &lt;code&gt;.git/config&lt;/code&gt; directly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[remote &amp;quot;origin&amp;quot;]
	url = git@git.sr.ht:~seirdy/seirdy.one
	fetch = +refs/heads/*:refs/remotes/origin/*
[remote &amp;quot;gl_upstream&amp;quot;]
	url = git@gitlab.com:seirdy/seirdy.one.git
	fetch = +refs/heads/*:refs/remotes/gl_upstream/*
[remote &amp;quot;gh_upstream&amp;quot;]
	url = git@github.com:seirdy/seirdy.one.git
	fetch = +refs/heads/*:refs/remotes/gh_upstream/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If that&amp;rsquo;s too much work&amp;mdash;a perfectly understandable complaint&amp;mdash;automating the process is trivial. Here&amp;rsquo;s &lt;a href=&#34;https://git.sr.ht/~seirdy/dotfiles/tree/master/Executables/shell-scripts/bin/git-remote-setup&#34;&gt;an example from my dotfiles&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;seamless-pushing-and-pulling&#34;&gt;Seamless pushing and pulling&lt;/h2&gt;
&lt;p&gt;Having multiple remotes is fine, but pushing to and fetching from all of them can be slow. Two simple git aliases fix that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[alias]
	pushall = !git remote | grep -E &#39;origin|upstream&#39; | xargs -L1 -P 0 git push --all --follow-tags
	fetchall = !git remote | grep -E &#39;origin|upstream&#39; | xargs -L1 -P 0 git fetch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, &lt;code&gt;git pushall&lt;/code&gt; and &lt;code&gt;git fetchall&lt;/code&gt; will push to and fetch from all remotes in parallel, respectively. Only one remote needs to be online for project members to keep working.&lt;/p&gt;
&lt;h2 id=&#34;advertising-remotes&#34;&gt;Advertising remotes&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d recommend advertising at least three remotes in your README: your personal favorite and two determined by popularity. Tell users to run &lt;code&gt;git remote set-url&lt;/code&gt; to switch remote locations if one goes down.&lt;/p&gt;
&lt;h2 id=&#34;before-you-ask&#34;&gt;Before you ask&amp;hellip;&lt;/h2&gt;
&lt;p&gt;Q: Why not use a cloud service to automate mirroring?&lt;/p&gt;
&lt;p&gt;A: Such a setup depends upon the cloud service and a primary repo for that service to watch, defeating the purpose (resiliency). Hydra hosting automates this without introducing new tools, dependencies, or closed platforms to the mix.&lt;/p&gt;
&lt;p&gt;Q: What about issues, patches, etc.?&lt;/p&gt;
&lt;p&gt;A: Stay tuned for Parts 2 and 3, coming soon to a weblog/gemlog near you™.&lt;/p&gt;
&lt;p&gt;Q: Why did you call this &amp;ldquo;hydra hosting&amp;rdquo;?&lt;/p&gt;
&lt;p&gt;A: It&amp;rsquo;s a reference to the Hydra of Lerna from Greek Mythology, famous for &lt;span data-literal=&#34;having multiple heads that could grow back after beheading&#34;&gt;keeping its brain in a nested RAID array to protect against disk failures and beheading&lt;/span&gt;. It could also be a reference to a fictional organization of the same name from Marvel Comics named after the Greek monster for similar reasons.&lt;/p&gt;
</description>
    </item>
    
    <item><title>Resilient Git, Part 0: Introduction</title>
      <link>https://envs.net/~seirdy/posts/2020/11/17/git-workflow-0/</link>
      <pubDate>Tue, 17 Nov 2020 21:13:03 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2020/11/17/git-workflow-0/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2020/11/17/git-workflow-0/">&lt;div&gt;
&lt;p&gt;Recently, GitHub re-instated the &lt;a href=&#34;https://github.com/ytdl-org/youtube-dl&#34;&gt;youtube-dl git repository&lt;/a&gt; after following a takedown request by the RIAA under the DMCA. Shortly after the takedown, many members of the community showed great interest in &amp;ldquo;decentralizing git&amp;rdquo; and setting up a more resilient forge. What many of these people fail to understand is that the Git-based project setup is designed to support decentralization by being fully distributed.&lt;/p&gt;
&lt;p&gt;Following the drama, I&amp;rsquo;m putting together a multi-part guide on how to leverage the decentralized, distributed nature of git and its ecosystem. I made every effort to include all parts of a typical project.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I&amp;rsquo;ll update this post as I add articles to the series. At the moment, I&amp;rsquo;ve planned to write the following articles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://envs.net/~seirdy/2020/11/18/git-workflow-1/&#34;&gt;Hydra Hosting&lt;/a&gt;: repository hosting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Community feedback (issues, support, etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Community contributions (patches)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CI/CD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Distribution&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The result of the workflows this series covers will be minimal dependence on outside parties; all members of the community will easily be able to get a copy of the software, its code, development history, issues, and patches offline on their machines with implementation-neutral open standards. Following open standards is the killer feature: nothing in this workflow depends on a specific platform (GitHub, GitLab, Gitea, Bitbucket, Docker, Nix, Jenkins, etc.), almost eliminating your project&amp;rsquo;s &amp;ldquo;bus factor&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Providing a way to get everything offline, in a format that won&amp;rsquo;t go obsolete if a project dies, is the key to a resilient git workflow.&lt;/p&gt;
&lt;h2 id=&#34;before-we-start-faq&#34;&gt;Before we start: FAQ&lt;/h2&gt;
&lt;p&gt;Q: What level of experience does this series expect?&lt;/p&gt;
&lt;p&gt;A: Basic knowledge of git, and a very basic understanding of email. If you have a few repos and can use a third-party email client, you&amp;rsquo;re good.&lt;/p&gt;
&lt;p&gt;Q: Do you think you can get hundreds and thousands of people to drop Git{Hub,Lab,tea} and use a different workflow?&lt;/p&gt;
&lt;p&gt;A: No, but that would be nice. If only five people who read this series give this workflow a spin and two of them like it and keep using it, I&amp;rsquo;d be happy.&lt;/p&gt;
&lt;p&gt;Q: Is this workflow more difficult than my current one?&lt;/p&gt;
&lt;p&gt;A: &amp;ldquo;Difficult&amp;rdquo; is subjective. I recommend TRYING this before jumping to conclusions (or worse, sharing those conclusions with others before they have a chance to try it).&lt;/p&gt;
&lt;p&gt;Q: I&amp;rsquo;m not interested in trying anything new, no matter what the benefits are.&lt;/p&gt;
&lt;p&gt;A: First of all, that wasn&amp;rsquo;t a question. Second, this series isn&amp;rsquo;t for you. You should not read this. I recommend doing literally anything else.&lt;/p&gt;
&lt;p&gt;Next: Resilient Git, Part 1: &lt;a href=&#34;https://envs.net/~seirdy/2020/11/18/git-workflow-1/&#34;&gt;Hydra Hosting&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item><title>Hello World</title>
      <link>https://envs.net/~seirdy/posts/2020/11/02/hello-world/</link>
      <pubDate>Mon, 02 Nov 2020 19:06:56 +0000</pubDate>
      <author>seirdy@seirdy.one (Seirdy)</author>
      <guid>https://envs.net/~seirdy/posts/2020/11/02/hello-world/</guid>
      <description xml:base="https://envs.net/~seirdy/posts/2020/11/02/hello-world/">&lt;p&gt;Hello, world! This is my first post.&lt;/p&gt;
&lt;p&gt;It looks like I managed to somehow get this site working. You can look forward to a few more posts in the coming weeks.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
