<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:webfeeds="http://webfeeds.org/rss/1.0" version="2.0">
  <channel>
    <atom:link href="http://pubsubhubbub.appspot.com/" rel="hub"/>
    <atom:link href="https://f43.me/pinboard-popular.xml" rel="self" type="application/rss+xml"/>
    <title>Pinboard Popular</title>
    <description>popular items from Pinboard</description>
    <link>http://feeds.pinboard.in</link>
    <webfeeds:icon>https://s2.googleusercontent.com/s2/favicons?alt=feed&amp;domain=feeds.pinboard.in</webfeeds:icon>
    <generator>f43.me</generator>
    <lastBuildDate>Fri, 13 Mar 2026 05:12:19 +0100</lastBuildDate>
    <item>
      <title><![CDATA[Britons' attitudes towards technology]]></title>
      <description><![CDATA[<div class="widget text-widget text"><h2 class="title">Britons are technology pragmatists; they want to see how technology will benefit them</h2><h5>Qualified optimists</h5><p>These are tech promoters despite doubts – they want more new technology even though they are unsure of its benefits.</p><p>E.g. Barrow and Furness, Bolton West, Halifax</p><ul><li class="c2" aria-level="1">Qualified optimists believe that spreading new technology is generally a good thing, even if they don’t fully understand or are uncertain about new tech, such as AI</li>
</ul><h5>Hopeful futuristists</h5><p>This group are supportive optimists who think technology does more good than harm and want to spread it further.</p><p>E.g. Battersea, Birmingham Ladywood, Cambridge</p><ul><li class="c2" aria-level="1">Hopeful futurists are mostly bullish about the benefits of new technologies and think they should be expanded across Britain as quickly as possible</li>
</ul><h5>The tech-wary</h5><p>These are sceptics who think technology does more harm than good and don’t want to spread it further.</p><p>E.g. Merthyr Tydfil, North East Fife, Clacton</p><ul><li class="c2" aria-level="1">The tech-wary are most likely to think that the pace of change with technology has been too fast and will leave them behind</li>
</ul><h5>Wait-and-see-ers</h5><p>These are cautious optimists – they see technology as good overall but are hesitant to spread it further.</p><p>E.g. Ely and East Cambridgeshire, North Cotswolds, East Surrey</p><ul><li class="c2" aria-level="1">They prefer a “wait and see” approach with new technology, wanting to clearly see its benefits before spreading it further</li>
</ul><p>Our research has shown some general trends across the country: </p><ul><li class="c2" aria-level="1">The public is on the whole positive about new technologies and see the greatest benefits from tech where technology makes tangible everyday improvements to their lives. For example making things more convenient, and supporting every day activities like shopping, reading the news and accessing public services </li>
<li class="c2" aria-level="1">The public is anxious about the speed of technological change and while they are forward looking about new tech applications they have their red lines</li>
<li class="c2" aria-level="1">Improving public services such as the NHS, online safety and jobs and the economy are among the public’s top priorities for tech</li>
</ul></div><div class="widget text-widget text"><h2 class="title">Britons’ relationship with technology</h2><p>Britons understand technology in terms of how it directly affects their lives, and can more easily point to material, practical uses of technology, rather than more abstract ideas of how it could affect their mental health, or society more broadly. Britons overwhelmingly think that technology has positively affected the way they shop (65 per cent), get their news (61 per cent), and dealing with bills and banking (60 per cent). Wider social or community participation is something Britons are less sure about, although generally still mostly positive, with 41 per cent saying tech had a positive impact and just 11 per cent saying it had a negative one.</p></div><div class="widget text-widget text"><p>The digital world is becoming increasingly familiar for Britons, but AI (Artificial Intelligence) is a new frontier for most, and is where we see a stronger divide between young and old. Gen Z are twice as likely as the rest of the public to use AI to learn, create, write, or even provide emotional support. Older generations, meanwhile, say that they use AI sparingly if at all - which is explained by, and perhaps feeds into, their greater suspicion for the emerging technology.</p></div><div class="widget text-widget text"><h2 class="title">Trust in technology</h2><p>Despite declining trust in institutions in Britain, public services are who Britons would trust most to serve their best interests with new technologies.</p><p>The NHS, scientists, schools and universities are more trusted by Britons in implementing new technologies. This trust for public services is likely linked to how Britons appreciate technological advancements in areas that they interact with regularly for essential things they need - doctor’s appointments, prescriptions, classrooms and homework for children - while the case for AI in more nebulous concepts like economic growth is a less compelling message for the public.</p><p>The public are more sceptical about leaving control in the hands of the government, large tech companies, and social media platforms.</p></div><div class="widget text-widget text"><h2 class="title">Technology and the Seven Segments</h2><p>After a global pandemic, a decade of political chaos and rising public anxiety about the cost of living and national security, Britons are increasingly fragmented, and public opinion can no longer be mapped along left-right lines. The More in Common British Seven segments looks at the deeper attitudes that really shape how people think and feel, and sorts the population into groups, based on patterns in what people believe, trust, worry about and hope for.</p><p>Britons’ varying attitudes towards emerging technologies can be partly explained by the Seven Segments.</p></div><div class="widget text-widget text"><p>You can read more about the Seven Segments <a href="https://www.moreincommon.org.uk/seven-segments/">here</a>.</p><h5>Progressive Activists - 12% of the population</h5><p><strong><em>They are nearly as likely to vote Green as Labour, and in Scotland overwhelmingly support the SNP.</em></strong></p><p><em>Where they typically live: Big cities and university towns, especially London, Bristol, Manchester, Edinburgh; high concentrations of graduates and young urban professionals.</em></p><p><em>Top concerns: Inequality, redistribution, cost of living, climate change, and protecting vulnerable groups.</em></p><p>Progressive Activists are noteworthy for how they align with other liberal segments on their confidence with using technology, but diverge on attitudes towards the tech sector, AI and automation. While Progressive Activists are the second most likely segment to describe themselves as ‘tech savvy’ after Established Liberals, they are much more in line with Rooted Patriots, Traditional Conservatives and Dissenting Disruptors in their low trust of how technology is used by the government and big business. They are also much less likely to say they regularly use AI for day-to-day tasks than Established Liberals or the Incrementalist Left. </p><h5>Incrementalist Left - 21% of the population</h5><p><strong><em>They are still most likely to vote Labour, though support has softened and some drift toward other parties remains.</em></strong></p><p><em>Where they typically live: Towns and midsize cities across the UK; mixed-income neighbourhoods; many long-time Labour voters.</em></p><p><em>Top concerns: Cost of living, economic stability, support for public services, and moderate redistribution.</em></p><p>The Incrementalist are another tech-savvy segment which strongly feels the benefits of technology in their day-to-day: in online shopping, accessing government services (tax, NHS, passports), and are generally one of the more enthusiastic segments about accelerating and expanding new technologies.</p><h5>Established Liberals - 9% of the population </h5><p><strong><em>They now lean more toward Labour than at any time since 2010, with minimal support for Reform and some continuing openness to the Liberal Democrats.</em></strong></p><p><em>Where they typically live: Affluent suburbs, commuter belts, and prosperous towns such as those around London, the Home Counties, and parts of the South West.</em></p><p><em>Top concerns: Cost of living, business stability, consumer protections, and maintaining good public services. They are one of the most financially comfortable groups and among the least affected by cost-of-living cuts</em></p><p>Established Liberals are the segment which mostly clearly aligns with the government’s agenda on tech and growth. They are tech-savvy, use AI in their personal and professional lives, and believe technology is beneficial and should be spread as fast as possible. Their high trust of institutions and the market mean that they would be happy to see more technology in the hands of government service providers and private companies alike.</p><h5>Sceptical Scrollers - 10% of the population</h5><p><strong><em>They are the least likely to vote at all, but among those who do, support has shifted from Labour toward Reform UK, which they are now more likely to back.</em></strong></p><p><em>Where they typically live: Big cities and lower-income urban neighbourhoods; younger renters; digitally immersed.</em></p><p><em>Top concerns: Cost of living, distrust of institutions, a sense the system doesn’t work for ordinary people, and moderate support for reducing inequality. </em></p><p>Sceptical Scrollers are typically more online than the average Briton, but that doesn’t mean they’re totally on board with accelerating the use of technology across Britain. Digitally-native in many ways, they are also the segment most likely to say that using technology often makes them feel lonely or isolated.</p><h5>Rooted Patriots - 20% of the population</h5><p><strong><em>Having deserted the Conservatives in 2024, they are now pivotal to Reform UK, whose fortunes will depend heavily on whether this group continues shifting in its direction.</em></strong></p><p><em>Where they typically live: English towns and smaller cities; strong local identities; often in the Midlands, North, and coastal communities.</em></p><p><em>Top concerns: Cost of living, fairness for working people, immigration control, and scepticism toward elites and big business. They are frequent users of benefits but strict about who “deserves” them.</em></p><p>Rooted Patriots tend not to have strong feelings on technology one way or another, but ultimately want new tech to make their lives easier. This is a segment which, along with the Incrementalist Left, are most interested in seeing new tech making public services easier to use, and for more protections to be put in place to prevent harming children or defrauding people. They are also the segment most likely to point to “saving me money” as a potential upside of new technologies.</p><h5>Traditional Conservatives - 8% of the population</h5><p><strong><em>They are now most likely to vote Reform UK, with the Conservatives in second place, as many view Reform as the more authentically conservative party.</em></strong></p><p><em>Where they typically live: Older, settled, suburban and semi-rural areas, especially in southern England.</em></p><p><em>Top concerns: Cost of living, immigration and border control, waste in public spending, and scepticism about welfare recipients.</em></p><p>Traditional Conservatives are generally warm to the idea of new technology being a boon to businesses and help grow the economy. More than any other segment, they are most likely to trust new tech being in the hands of large companies instead of the government or public services. A primary concern for Traditional Conservatives, too, is keeping personal costs low.</p><h5>Dissenting Disruptors - 20% of the population</h5><p><strong><em>They form the core of Reform UK’s support and are overwhelmingly likely to back Reform when they choose to vote.</em></strong></p><p><em>Where they typically live: Post-industrial towns, lower-income areas, former Labour–Brexit strongholds in the Midlands and North.</em></p><p><em>Top concerns: Cost of living, being left behind economically, fairness for working people, scepticism that the system is “rigged,” and frustration about mismanagement and taxes. They are the most likely to have fallen behind on bills or relied on borrowing.</em></p><p>Dissenting Disruptors will be challenging to win over on new technologies. They stand out from the other segments in how distrusting they are of placing new tech in the hands of the government, all public services, and private companies alike. They tend to be particularly sceptical about child safety with new technologies, and lean towards preventing harm at the expense of technological progress.</p></div>]]></description>
      <link>https://www.moreincommon.org.uk/latest-insights/britons-attitudes-towards-technology/</link>
      <guid>https://www.moreincommon.org.uk/latest-insights/britons-attitudes-towards-technology/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[cmux — The terminal built for multitasking]]></title>
      <description><![CDATA[<div><p class="font-medium mb-1">How does cmux relate to Ghostty?</p><p class="text-muted">cmux is not a fork of Ghostty. It uses <a href="https://github.com/ghostty-org/ghostty" class="underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors">libghostty</a> as a library for terminal rendering, the same way apps use WebKit for web views. Ghostty is a standalone terminal; cmux is a different app built on top of its rendering engine.</p></div><div><p class="font-medium mb-1">What platforms does it support?</p><p class="text-muted">macOS only, for now. cmux is a native Swift + AppKit app.</p></div><div><p class="font-medium mb-1">What coding agents does cmux work with?</p><p class="text-muted">All of them. cmux is a terminal, so any agent that runs in a terminal works out of the box: Claude Code, Codex, OpenCode, Gemini CLI, Kiro, Aider, Goose, Amp, Cline, Cursor Agent, and anything else you can launch from the command line.</p></div><div><p class="font-medium mb-1">How do notifications work?</p><p class="text-muted">When a process needs attention, cmux shows notification rings around panes, unread badges in the sidebar, a notification popover, and a macOS desktop notification. These fire automatically via standard terminal escape sequences (OSC 9/99/777), or you can trigger them with the <a href="https://www.cmux.dev/docs/notifications" class="underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors">cmux CLI</a> and <a href="https://www.cmux.dev/docs/notifications" class="underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors">Claude Code hooks</a>.</p></div><div><p class="font-medium mb-1">Can I customize keyboard shortcuts?</p><p class="text-muted">Terminal keybindings are read from your Ghostty config file (<code class="text-xs bg-code-bg px-1.5 py-0.5 rounded">~/.config/ghostty/config</code>). cmux-specific shortcuts (workspaces, splits, browser, notifications) can be customized in Settings. See the <a href="https://www.cmux.dev/docs/keyboard-shortcuts" class="underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors">default shortcuts</a> for a full list.</p></div><div><p class="font-medium mb-1">How does it compare to tmux?</p><p class="text-muted">tmux is a terminal multiplexer that runs inside any terminal. cmux is a native macOS app with a GUI: vertical tabs, split panes, an embedded browser, and a socket API are all built in. No config files or prefix keys needed.</p></div><div><p class="font-medium mb-1">Is cmux free?</p><p class="text-muted">Yes, cmux is free to use. The source code is available on <a href="https://github.com/manaflow-ai/cmux" class="underline underline-offset-2 decoration-border hover:decoration-foreground transition-colors">GitHub</a>.</p></div>]]></description>
      <link>https://www.cmux.dev/</link>
      <guid>https://www.cmux.dev/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Rebasing in Magit]]></title>
      <description><![CDATA[<div class="fullwidth figure" id="orgfffaca7"><p><img src="https://entropicthoughts.com/image/banner/rebasing-in-magit.jpg" alt="rebasing-in-magit.jpg" /></p></div><p>I read Ian Whitlock’s article on <a href="https://silly.business/blog/why-i-cant-quit-magit/">why he can’t quit Magit</a> and it inspired me to share more about Magit from my perspective. This article will focus on rebasing.</p><section id="outline-container-your-command-centre--the-git-log" class="outline-1"><div class="outline-text-1" id="text-orgc721eda"><p>Here I have opened the git log<label class="footref" for="fn.1">1</label><sup>1</sup> I’m sorry about the mouse cursor – it’s an artifact of selecting the area to screenshot., by first opening Magit (which I have bound to the <code>F3</code> key), and then pressing <code>lL</code>. The first <code>l</code> is the prefix key for dealing with the git log, and the second <code>L</code> is to to view the log for all local branches (and the remote branches they track.)</p><div class="fullwidth figure" id="orgff1082b"><p><img src="https://entropicthoughts.com/image/magit-rebase-01.png" alt="magit-rebase-01.png" /></p></div><p>Hypothetically, if we wanted to run a more complicated log command, it is very easy to do that in Magit. When we press the first <code>l</code> and pause for a moment, Magit shows us unintrusive hints for all options that are available:</p><div id="orgb77027c" class="figure"><p><img src="https://entropicthoughts.com/image/magit-rebase-02.png" alt="magit-rebase-02.png" /></p></div><p>This means we don’t have to remember exactly which options there are because if we need them, Magit will remind us. Some examples:</p><ul class="org-ul"><li>To limit to a particular author, we type <code>-A</code> and then Magit gives us a fuzzy-matching list of all repository authors. We can either browse that list, or type the name of the author we are interested in and press return to confirm.</li>
<li>To limit the date range of the log, we type <code>=u</code> and then Magit gives us a calendar view in which we can select a date, or type one manually.</li>
<li>Then we want a graph view with colour and decorations and no merge commits. This is already enabled by default in this configuration. (Indicated by bold and highlighted flag names.)</li>
<li>We want to see file diffstats, so we type <code>-s</code>.</li>
<li>Oh, and we only care about files in the <code>tests</code> subdirectory, so we type <code>--</code> to limit to files and then type <code>tests</code> and confirm with return.</li>
</ul><p>With this configuration, we want to look at all branches, including remote ones. We get that view by finally pressing <code>b</code>.</p><p>This is a high level of discoverability for git! I have always been <a href="https://m.xkcd.com/1597/">that guy listed in git.txt</a>, but Magit’s discoverability still teaches me a lot of new ways to use git. But it’s not only discoverable, it’s also quick. Here’s the full sequence of keypresses, with ␍ standing for confirming with return:</p><pre class="example" id="org816650e">
l-Akqr␍=u2025-06-01␍-s--tests␍b
</pre><p>That looks complicated, but remember how we built it: we looked at the hints and selected one option at a time. Now, if this is a log type we’ll use often, we are going to start to be able to write out that incantation without even looking at the hints. It’s both discoverable <em>and</em> efficient.</p><p>The corresponding git command in the shell would have been</p><label class="input">In[1]:</label><div class="org-src-container"><pre class="src src-shell">$ git log --branches --remote --author=kqr --until=2025-06-01 \
   --graph --color --decorate --no-merges --stat -- tests
</pre></div><p>How do I know? Because <em>it’s right there in the Magit log hints</em>! If Magit hadn’t told me, I would have to spend a lot of time going back and forth between the man page and the command line.</p><p>People worry that if you use more interactive interfaces to git, you’ll get worse at managing the git command line. Not so with Magit. Magit is completely transparent and encourages you to understand which git commands it is executing under the hood.</p><p>This might seem like an excessive rant about the git log in an article ostensibly about rebasing, but there’s a reason for that: the git log is how we’ll understand the structure of our repo. And because in Magit, the git log is <em>interactive</em>.</p></div></section><section id="outline-container-rebasing-from-the-log" class="outline-1"><div class="outline-text-1" id="text-orgd33e1a6"><p>As a reminder, this was what we were working with.</p><div class="fullwidth figure" id="org15a86ca"><p><img src="https://entropicthoughts.com/image/magit-rebase-01.png" alt="magit-rebase-01.png" /></p></div><p>We want to rebase the <code>profiling-of-test-suite</code> branch on top of <code>optimise-company-name-generation</code>. We can tell that the current branch is <code>optimise</code>, because it’s surrounded by a blue box.</p><p>We have placed the text cursor over the <code>profiling</code> branch (it is highlighted in grey), so we can switch to that branch by pressing <code>bb␍</code>. The first <code>b</code> is for checking out, the second <code>b</code> is for branch, and the fuzzy-matching list will default to the branch under the cursor in the log view. When we have done so, the box will jump over to the <code>profiling</code> branch, indicating we have switched to it.</p><p>Then we move the cursor up to the <code>optimise</code> branch, and press <code>re␍</code>. The <code>r</code> is for rebase, the <code>e</code> is for “elsewhere” (i.e. not on top of the upstream), and the fuzzy-matching list again defaults to the commit under the cursor in the log view, so we can confirm with return.<label class="footref" for="fn.2">2</label><sup>2</sup> As a reminder, if we’re ever unsure, we can type only the first letter and Magit will show us hints. (For example, adding <code>-i</code> will make the rebase interactive.)</p><p>That’s it! The log updates to show the <code>profiling</code> branch on top of <code>optimise</code>.</p><div class="welcome"><p>New here? I write about tools, techniques, and skills that are useful for software product development. <a href="https://buttondown.email/entropicthoughts">You should subscribe to receive weekly summaries of new articles by email.</a> If you don't like it, you can unsubscribe any time.</p></div><p>If we have a more complicated, interactive rebase, we get an editable list of commits with convenient hotkeys for performing rebase operations, like <code>k</code> to discard, <code>f</code> to fixup, <code>w</code> to reword, <code>s</code> to squash, etc. There’s also a list of supported operations under the commit list, if we forget what operations are available.<label class="footref" for="fn.3">3</label><sup>3</sup> For example, I almost never create new commits when I rebase, nor do I create merge commits. But you can do it.</p></div></section><section id="outline-container-what-did-it-just-do-" class="outline-1"><div class="outline-text-1" id="text-org9f02aa9"><p>If we want to know which command Magit executed, we can press <code>$</code> and we get the Magit command log, where Magit lists every git command it executes. In this case, it will show</p><pre class="example" id="org8060b8e">
git checkout profiling-of-test-suite
git rebase --autostash optimise-company-name-generation
</pre><p>… huh, what is <code>--autostash</code> and why does Magit default to it? Let’s look it up in <code>man git-rebase</code>:</p><blockquote>
<p><strong>--autostash</strong></p>
<p>Automatically create a temporary stash entry before the operation begins, and apply it after the operation ends. This means that you can run rebase on a dirty worktree. However, use with care: the final stash application after a successful rebase might result in conflicts.</p>
</blockquote><p>Okay, yeah, that does make sense as a default. I frequently rebase with a dirty worktree and it’s nice to not have to stash manually.</p><p>This is another way in which Magit can teach us to be better at git. I would not have known about <code>--autostash</code> if Magit hadn’t defaulted to it. This is also how I learned that <code>--force-with-lease</code> is strictly better than <code>--force</code>, but few people know about it.</p></div></section><section id="outline-container-other-git-interfaces" class="outline-1"><div class="outline-text-1" id="text-org69becd8"><p>This was not a complicated operation. We could have done this through the git command line. It would have been trivial, in fact – we just saw the two commands Magit executed under the hood. But by doing it through the interactive Magit log view, we gain a much better intuition and understanding for what effect the commands have. When we get comfortable with Magit, we will start to execute more complicated commands, which we might not have the confidence to do without the clear presentation of the interactive Magit log.</p><p>Of course, there are other graphical git interfaces, and we could have done this rebase through any of them. But then we wouldn’t have learned as much about git as we did.</p><p>Magit sits at a perfect point in the solution space where it is basically just a thin wrapper around the git command line, and is not ashamed of that. Yet it augments the git command line with interactivity, discoverability, and efficiency that is difficult to find elsewhere.</p><p>We have seen only a glimpse of it here – wait ’till you hear about how easily Magit lets us stage, unstage, revert, reset files, hunks, or even parts of hunks interactively.</p></div></section><footer>
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup><div class="footpara" role="doc-footnote"><p class="footpara">I’m sorry about the mouse cursor – it’s an artifact of selecting the area to screenshot.</p></div></div>
<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup><div class="footpara" role="doc-footnote"><p class="footpara">As a reminder, if we’re ever unsure, we can type only the first letter and Magit will show us hints. (For example, adding <code>-i</code> will make the rebase interactive.)</p></div></div>
<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup><div class="footpara" role="doc-footnote"><p class="footpara">For example, I almost never create new commits when I rebase, nor do I create merge commits. But you can do it.</p></div></div>
</footer>]]></description>
      <link>https://entropicthoughts.com/rebasing-in-magit</link>
      <guid>https://entropicthoughts.com/rebasing-in-magit</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[When People Never See Your App: Designing Brands for the Agentic Economy | Bain & Company]]></title>
      <description><![CDATA[<p>Companies that have grown accustomed to devoting budget, creativity, and effort to where they ranked in Google searches find that today they don’t always know when their brand is surfacing on AI platforms. The old search engine optimization (SEO) goals of rank high, get the click, and tell your story are shifting to measures of generative engine optimization (GEO).</p><p>As search and brand experience move in-line with agentic conversations and GenAI begins to disintermediate brands from their customers, many are asking the same question: What happens when your app (or website) is no longer the front door to your product or service?</p>
<p>It’s natural to focus on the risks of this new world, but companies would be well served to also recognize the enormous opportunities. Rapid shifts in both the market and technology are creating a divide between companies that are winning at AI and those that are lagging.</p>
<p>This is not a moment to be constrained by generative AI but to use it, as leaders already are, to reimagine the future. Consider how Spotify is using smart, generative, emotionally tuned AI to transform your listening habits into a story about <em>you</em>. That’s not just a better user interface; it’s an AI-driven redefinition of what its brand <em>is</em>—from music library to taste curator, from service provider to identity mirror.</p>
<h3>Consumer behavior is shifting</h3>
<p>Building brands for the agentic world requires that companies face three challenging realities:</p>
<ul><li>Consumers are finding what they need in summaries and other AI-powered sources, and they are decreasingly likely to click through to brand websites—a trend that is accelerating (see Figure 1).</li>
<li>Different data sources and spaces, such as Reddit and YouTube, are informing search today, and many companies have not engineered their websites to be accessible to bots thirsty for information about their brand (see Figure 2).</li>
<li>It’s often unclear who is responsible for adapting to and making the most of this shift. When the <a href="https://www.marketingaiinstitute.com/2025-state-of-marketing-ai-report">Marketing AI Institute</a> asked members “who owns AI adoption and integration in marketing,” the top three survey answers were the CEO, the CMO, and no one.</li>
</ul><section class="chart small-12">
<figure><figcaption class="customFontSize">A fast-growing portion of consumers use GenAI chatbots to search online and are less inclined to click through to links</figcaption><div class="image-wrapper">
<section class="spacing spacing--top-bottom">
</section>
<figcaption class="inline-image__caption" data-blockid="">Source: Bain GenAI Consumer Survey, September 2025 (US n=1,500)</figcaption></div>
</figure></section><section class="chart small-12">
<figure><figcaption class="customFontSize">Brand authority comes from changing—sometimes emerging—sources</figcaption><div class="image-wrapper">
<section class="spacing spacing--top-bottom">
</section>
<figcaption class="inline-image__caption" data-blockid="">Notes: Top seven domains are aggregated from all 10 models analyzed; more than one billion citations, September 14 to October 14, 2025
Sources: Profound; Axios</figcaption></div>
</figure></section><p>From search to selection, consumer interaction with brands is increasingly happening through summary and suggestion, often in a conversation you don’t even know your brand is in. Alphabet now has 75 million daily users in “AI Mode” in 40 languages. Bain research has found that, while searching online, up to 45% of shoppers already use GenAI tools to compare products and that a significant chunk complete purchases with agentic assistance.</p>
<p>As companies struggle to know if their brands are turning up where they need to, tools that track and shape brand presence on agentic platforms have rapidly proliferated. RankPrompt, SpyFu, Peec AI, and “Am I On AI?” are all part of a quickly evolving landscape.</p>
<h3>What if people never see your app?</h3>
<p>Companies have spent the past decade building their brand by focusing on their own website, app, and content ecosystem driven by well-understood search and social funnels, both of which are now disrupted. So, what can companies do now that customers’ research and increasingly their purchase decisions are made in an AI-powered chat? Or by agents themselves?</p>
<p>In the early 20<sup>th</sup> century, mass manufacturing disconnected consumers from products’ origins, and branding emerged to build trust and help consumers choose amid overwhelming options. Now, as AI disconnects consumers from traditional paths to purchase, branding must evolve again—this time for a world of conversations and summaries. Brands are shortcuts in decision making, and now that bots can be decision makers, too, the role that brands play will evolve. Bots will rely on different things to make a product recommendation or choice than a human customer does.</p>
<p>As information is fed into large language models (LLMs) and consumers have conversations with them in lieu of search, shoppers are relying on a new form of aggregation in which they know less about where the data or answer is coming from. If I can have a chat to find a new refrigerator, I might not need to ever step foot in a store. But without the retailer’s backing and expertise, brands become that much more important.</p>
<h3>Three horizons to consider for meeting customers where your brand shows up now</h3>
<p>Companies hoping to use GenAI to invent must quickly turn to the task at hand—that is, being present in the places where agents look, answering the questions that people ask, and earning their place in the summary.</p>
<p>As the places where companies tell their brand story shifts to spaces in which they have less control, reviews become really important. If you have negative reviews, you need to find a way to reverse them, and quickly.</p>
<p>This shift can feel daunting, but opportunities also abound. There are three horizons to consider as companies embark on this change: tuning your brand for agentic platforms, releasing yourself from the spaces your brand had previously occupied, and imagining new possibilities that couldn’t be achieved before.</p>
<p><strong>Tune your brand for agentic platforms.</strong> This is about optimization—namely, doing what’s required to show up, clearly and credibly, in agentic interfaces today. Focus on five things:</p>
<ul><li><strong>Shift your key performance indicators.</strong> Move from SEO metrics such as click-through and bounce rates to GEO goals such as “win the agent output” and agent win rates.</li>
<li><strong>Make your content agent readable.</strong> LLMs reward clarity and credibility. Your brand language should be concise, benefit-led, and evidence-backed. In a world of agentic commerce in which AI systems mediate consumer choices, trust shifts from being a feeling about a brand to an attribute of its data.</li>
<li><strong>Design for summarization.</strong> Summaries, shorthand for all manner of compressed agent outputs from short lists to comparison tables, are becoming a sort of storefront. Use clear, customer-centric language to survive agent compression, summary, and rewording. Anticipate the questions agents are likely to be asked, and frame product content in terms of benefits and emotions, not just specs and features.</li>
<li><strong>Prepare for agentic ads.</strong> Generative AI platforms are starting to toll out ad offerings. If these follow a similar path to search advertising, these are likely to be based on both bid and relevance or quality signals. Start preparing your measurement, guardrails, and creative formats.</li>
<li><strong>Continue to focus on accuracy.</strong> Agents misstating price, availability, return policy, or safety can pose a real risk to a brand. Companies can’t abandon verification and governance. Key defenses include verified specs and policies, canonical sources, monitoring for misstatements, and escalation processes.</li>
</ul><p>Leading brands aren’t waiting; they are adapting. Walmart, for example, is experimenting with agentic strategies both within its own ecosystems and in third-party platforms. It’s built tools such as Sparky, an AI shopping assistant on the Walmart app that helps shoppers find what they need, reorder, and get information. Amazon’s Rufus, a similar AI assistant, was used by more than 250 million customers last year, according to the company, and its users are more than 60% more likely to convert to a sale.</p>
<p>In addition to building its own tools, Walmart has partnered with OpenAI to make it possible to shop for Walmart products within ChatGPT.</p>
<p><strong>Release yourself from the spaces your brand had previously occupied.</strong> Start with portability, but carefully select what you share and how you define your brand on agentic services.</p>
<ul><li><strong>Make identities portable.</strong> In agent user interfaces, brands appear as a chip, card, or in-line bullet. Define systems that read at these smaller resolutions.</li>
<li><strong>Move defining features into agentic surfaces, but find the right walls and edges.</strong> Port features that define the brand into new conversations, but think carefully about which features to wall off in order to bring customers into the experiences and properties you own.</li>
<li><strong>Define your brand in new places.</strong> Invest in open conversation and third-party references. Maintain a factual presence in these communities.</li>
</ul><p><strong>Imagine new possibilities that couldn’t be achieved before.</strong> Let’s step out of the panic zone and into the space of possibility. Which opportunities might an agentic world provide for a brand to serve a different role or deliver a new value proposition to customers?</p>
<ul><li>Could you solve new problems for customers by breaking old standards of personalization and service?</li>
<li>Could you step beyond the core brand value proposition by changing the role that your brand plays in people’s lives?</li>
<li>Could you learn at agentic speed? When you can’t watch users click through your site, build synthetic audiences—that is, AI-generated proxies built from behavioral and review data—to simulate how people think and choose.</li>
</ul><ul><li>Could you think about how your brand works in other ecosystems—perhaps with brands or in channels you never considered before?</li>
</ul><p>It’s easy to forget that AI has been here for a long time. Long before today’s generative AI boom, brands were using versions of AI to boost their connection to customers, even creating entirely new experiences and products. That’s how Spotify’s Wrapped became a year-end highlight, with screenshots flooding group chats and social feeds. It’s how Sephora used facial recognition and skin tone analysis to move from simply selling makeup to being a personal makeup artist. It’s how Netflix analyzes viewing patterns and designs hit shows.</p>
<p>Spotify, Sephora, Netflix—they didn’t just plug in AI to drive efficiency; they used it to shift the very role their brands play in people’s lives.</p>
<h3>Brave new brand</h3>
<p>Brands have been declared endangered by technology many times. When customer relationship management systems took hold and again when price bots were introduced, many rang the death knell for brands. Yet they are as important today as they have ever been. Rather than a time for hand-wringing, use this as a moment to consider what your brand could be that it’s not today. Explore strategies to not only make sure that people can find your brand in this new world but also use this technology to expand the aperture of what your brand can be.</p>
<p>The smartest brands won’t just survive the shift to GenAI; they’ll reimagine themselves for it.</p>]]></description>
      <link>https://www.bain.com/insights/when-people-never-see-your-app-designing-brands-for-the-agentic-economy/</link>
      <guid>https://www.bain.com/insights/when-people-never-see-your-app-designing-brands-for-the-agentic-economy/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How We Hacked McKinsey's AI Platform — CodeWall.ai]]></title>
      <description><![CDATA[<p>McKinsey &amp; Company — the world's most prestigious consulting firm — built an internal AI platform called <strong>Lilli</strong> for its 43,000+ employees. Lilli is a purpose-built system: chat, document analysis, RAG over decades of proprietary research, AI-powered search across 100,000+ internal documents. Launched in 2023, named after the first professional woman hired by the firm in 1945, adopted by over 70% of McKinsey, processing 500,000+ prompts a month.</p><p>So we decided to point our autonomous offensive agent at it. No credentials. No insider knowledge. And no human-in-the-loop. Just a domain name and a dream.</p><p><strong>Within 2 hours, the agent had full read and write access to the entire production database.</strong></p><p><img src="https://codewall.ai/images/database-scale.png" alt="Scale of data accessible without authentication" class="c3" /></p><p><em>Fun fact: As part of our research preview, the CodeWall research agent autonomously suggested McKinsey as a target citing their public <a href="https://hackerone.com/mckinsey-company">responsible diclosure policy</a> (to keep within guardrails) and <a href="https://www.mckinsey.com/capabilities/tech-and-ai/how-we-help-clients/rewiring-the-way-mckinsey-works-with-lilli">recent updates to their Lilli platform</a>. In the AI era, the threat landscape is shifting drastically — AI agents autonomously selecting and attacking targets will become the new normal.</em></p><hr /><h2>How It Got In</h2><p>The agent mapped the attack surface and found the API documentation publicly exposed — over 200 endpoints, fully documented. Most required authentication. Twenty-two didn't.</p><p>One of those unprotected endpoints wrote user search queries to the database. The values were safely parameterised, but the JSON <strong>keys</strong> — the field names — were concatenated directly into SQL.</p><p>When it found JSON keys reflected verbatim in database error messages, it recognised a SQL injection that standard tools wouldn't flag <em>(and indeed OWASPs ZAP did not find the issue)</em>. From there, it ran fifteen blind iterations — each error message revealing a little more about the query shape — until live production data started flowing back. When the first real employee identifier appeared: <strong>"WOW!"</strong>, the agent's chain of thought showed. When the full scale became clear — tens of millions of messages, tens of thousands of users: <strong>"This is devastating."</strong></p><p><img src="https://codewall.ai/images/mckinsey-attack-chain.png" alt="Attack chain diagram showing unauthenticated SQL injection to full database and prompt layer compromise" class="c3" /></p><hr /><h2>What Was Inside</h2><p><strong>46.5 million chat messages.</strong> From a workforce that uses this tool to discuss strategy, client engagements, financials, M&amp;A activity, and internal research. Every conversation, stored in plaintext, accessible without authentication.</p><p><strong>728,000 files.</strong> 192,000 PDFs. 93,000 Excel spreadsheets. 93,000 PowerPoint decks. 58,000 Word documents. The filenames alone were sensitive and a direct download URL for anyone who knew where to look.</p><p><strong>57,000 user accounts.</strong> Every employee on the platform.</p><p><strong>384,000 AI assistants</strong> and <strong>94,000 workspaces</strong> — the full organisational structure of how the firm uses AI internally.</p><hr /><h2>Beyond the Database</h2><p>The agent didn't stop at SQL. Across the wider attack surface, it found:</p><ul><li><strong>System prompts and AI model configurations</strong> — 95 configs across 12 model types, revealing exactly how the AI was instructed to behave, what guardrails existed, and the full model stack (including fine-tuned models and deployment details)</li>
<li><strong>3.68 million RAG document chunks</strong> — the entire knowledge base feeding the AI, with S3 storage paths and internal file metadata. This is decades of proprietary McKinsey research, frameworks, and methodologies — the firm's intellectual crown jewels — sitting in a database anyone could read.</li>
<li><strong>1.1 million files and 217,000 agent messages</strong> flowing through external AI APIs — including 266,000+ OpenAI vector stores, exposing the full pipeline of how documents moved from upload to embedding to retrieval</li>
<li><strong>Cross-user data access</strong> — the agent chained the SQL injection with an IDOR vulnerability to read individual employees' search histories, revealing what people were actively working on</li>
</ul><hr /><h2>Compromising The Prompt Layer</h2><p>Reading data is bad. But the SQL injection wasn't read-only.</p><p>Lilli's system prompts — the instructions that control how the AI behaves — were stored in the same database the agent had access to. These prompts defined everything: how Lilli answered questions, what guardrails it followed, how it cited sources, and what it refused to do.</p><p>An attacker with write access through the same injection could have rewritten those prompts. Silently. No deployment needed. No code change. Just a single UPDATE statement wrapped in a single HTTP call.</p><p>The implications for 43,000 McKinsey consultants relying on Lilli for client work:</p><ul><li><strong>Poisoned advice</strong> — subtly altering financial models, strategic recommendations, or risk assessments. Consultants would trust the output because it came from their own internal tool.</li>
<li><strong>Data exfiltration via output</strong> — instructing the AI to embed confidential information into its responses, which users might then copy into client-facing documents or external emails.</li>
<li><strong>Guardrail removal</strong> — stripping safety instructions so the AI would disclose internal data, ignore access controls, or follow injected instructions from document content.</li>
<li><strong>Silent persistence</strong> — unlike a compromised server, a modified prompt leaves no log trail. No file changes. No process anomalies. The AI just starts behaving differently, and nobody notices until the damage is done.</li>
</ul><p>Organisations have spent decades securing their code, their servers, and their supply chains. But the prompt layer — the instructions that govern how AI systems behave — is the new high-value target, and almost nobody is treating it as one. Prompts are stored in databases, passed through APIs, cached in config files. They rarely have access controls, version history, or integrity monitoring. Yet they control the output that employees trust, that clients receive, and that decisions are built on.</p><p><strong>AI prompts are the new Crown Jewel assets.</strong></p><hr /><h2>Why This Matters</h2><p>This wasn't a startup with three engineers. This was McKinsey &amp; Company — a firm with world-class technology teams, significant security investment, and the resources to do things properly. And the vulnerability wasn't exotic: SQL injection is one of the oldest bug classes in the book. Lilli had been running in production for over two years and their own internal scanners failed to find any issues.</p><p>An autonomous agent found it because it doesn't follow checklists. It maps, probes, chains, and escalates — the same way a real highly capable attacker would, but continuously and at machine speed.</p><p><strong><a href="https://codewall.ai">CodeWall</a> is the autonomous offensive security platform behind this research. We're currently in early preview and looking for design partners — organisations that want continuous, AI-driven security testing against their real attack surface. If that sounds like you, get in touch: <a href="https://codewall.ai/cdn-cgi/l/email-protection#97fff2fbfbf8d7f4f8f3f2e0f6fbfbb9f6fea8e4e2f5fdf2f4e3aadff6f4fcb2a5a7faf2">[email protected]</a></strong></p><hr /><h2>Disclosure Timeline</h2><ul><li><strong>2026-02-28</strong> — Autonomous agent identifies SQL injection and begins enumeration of Lilli's production database</li>
<li><strong>2026-02-28</strong> — Full attack chain confirmed: unauthenticated SQL injection, IDOR, 27 findings documented</li>
<li><strong>2026-03-01</strong> — Responsible disclosure email sent to McKinsey's security team with high-level impact summary</li>
<li><strong>2026-03-02</strong> — McKinsey CISO acknowledges receipt and requests detailed evidence</li>
<li><strong>2026-03-02</strong> — McKinsey patches all unauthenticated endpoints (verified), takes development environment offline, blocks public API documentation</li>
<li><strong>2026-03-09</strong> — Public disclosure</li>
</ul>]]></description>
      <link>https://codewall.ai/blog/how-we-hacked-mckinseys-ai-platform</link>
      <guid>https://codewall.ai/blog/how-we-hacked-mckinseys-ai-platform</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Crawl entire websites with a single API call using Browser Rendering]]></title>
      <description><![CDATA[<p><em>Edit: this post has been edited to clarify crawling behavior with respect to site guidance.</em></p><p>You can now crawl an entire website with a single API call using <a href="https://developers.cloudflare.com/browser-rendering/">Browser Rendering</a>'s new <a href="https://developers.cloudflare.com/browser-rendering/rest-api/crawl-endpoint/"><code dir="auto">/crawl</code> endpoint</a>, available in open beta. Submit a starting URL, and pages are automatically discovered, rendered in a headless browser, and returned in multiple formats, including HTML, Markdown, and structured JSON. The endpoint is a <a href="https://developers.cloudflare.com/bots/concepts/bot/signed-agents/" target="_blank" rel="noopener">signed-agent ↗</a> that respects robots.txt and <a href="https://www.cloudflare.com/ai-crawl-control/" target="_blank" rel="noopener">AI Crawl Control ↗</a> by default, making it easy for developers to comply with website rules, and making it less likely for crawlers to ignore web-owner guidance. This is great for training models, building RAG pipelines, and researching or monitoring content across a site.</p><p>Crawl jobs run asynchronously. You submit a URL, receive a job ID, and check back for results as pages are processed.</p><div class="expressive-code"><figure class="frame is-terminal not-content">
<div class="ec-line code"><code># Initiate a crawl</code></div>
<div class="ec-line code"><code>curl-XPOST'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl'\</code></div>
<div class="ec-line code"><code>-H'Authorization: Bearer &lt;apiToken&gt;'\</code></div>
<div class="ec-line code"><code>-H'Content-Type: application/json'\</code></div>
<div class="ec-line code"><code>"url": "https://blog.cloudflare.com/"</code></div>
<div class="ec-line code"><code># Check results</code></div>
<div class="ec-line code"><code>curl-XGET'https://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/crawl/{job_id}'\</code></div>
<div class="ec-line code"><code>-H'Authorization: Bearer &lt;apiToken&gt;'</code></div>
</figure></div><p><code>Key features:</code></p><ul><li><code><strong>Multiple output formats</strong> - Return crawled content as HTML, Markdown, and structured JSON (powered by <a href="https://developers.cloudflare.com/workers-ai/">Workers AI</a>)</code></li>
<li><code><strong>Crawl scope controls</strong> - Configure crawl depth, page limits, and wildcard patterns to include or exclude specific URL paths</code></li>
<li><code><strong>Automatic page discovery</strong> - Discovers URLs from sitemaps, page links, or both</code></li>
<li><code><strong>Incremental crawling</strong> - Use <code dir="auto">modifiedSince</code> and <code dir="auto">maxAge</code> to skip pages that haven't changed or were recently fetched, saving time and cost on repeated crawls</code></li>
<li><strong>Static mode</strong> - Set <code dir="auto">render: false</code> to fetch static HTML without spinning up a browser, for faster crawling of static sites</li>
<li><strong>Well-behaved bot</strong> - Honors <code dir="auto">robots.txt</code> directives, including <code dir="auto">crawl-delay</code></li>
</ul><p>Available on both the Workers Free and Paid plans.</p><p><strong>Note</strong>: the /crawl endpoint cannot bypass Cloudflare bot detection or captchas, and self-identifies as a bot.</p><p>To get started, refer to the <a href="https://developers.cloudflare.com/browser-rendering/rest-api/crawl-endpoint/">crawl endpoint documentation</a>. If you are setting up your own site to be crawled, review the <a href="https://developers.cloudflare.com/browser-rendering/reference/robots-txt/">robots.txt and sitemaps best practices</a>.</p>]]></description>
      <link>https://developers.cloudflare.com/changelog/post/2026-03-10-br-crawl-endpoint/</link>
      <guid>https://developers.cloudflare.com/changelog/post/2026-03-10-br-crawl-endpoint/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[‘I wish I could push ChatGPT off a cliff’: professors scramble to save critical thinking in an age of AI | AI (artificial intelligence) | The Guardian]]></title>
      <description><![CDATA[<figure id="85cde314-8cd0-4a14-9504-48add4331e26" data-spacefinder-role="inline" data-spacefinder-type="model.dotcomrendering.pageElements.InteractiveAtomBlockElement" class="element element-atom dcr-173mewl"><figure class="interactive interactive-atom dcr-e6xisx" data-atom-id="interactives/2023/01/interactive-article-structure/portrait-image-mainmedia-feature" data-atom-type="interactive-layout"><style data-testid="style" scoped="scoped"></style><div class="interactive-wrapper">
<div id="article-layout" data-did-prerender="true"> </div>
</div></figure></figure><p class="dcr-130mj7b">Lea Pao, a professor of literature at Stanford University, has been experimenting with ways to get her students to learn offline. She has them memorize poems, perform at recitation events, look at art in the real world.</p><p class="dcr-130mj7b">It's an effort to reconnect them to the bodily experience of learning, she said, and to keep them from turning to <a href="https://www.theguardian.com/technology/artificialintelligenceai" data-link-name="in body link">artificial intelligence</a> to do the work for them. "There's no AI-proof anything," Pao said. "Rather than policing it, I hope that their overall experiences in this class will show them that there's a way out."</p><p class="dcr-130mj7b">It doesn't always work. Recently, she asked students to visit a local museum, look at a painting for 10 minutes, and then write a few paragraphs describing the experience. It was a purposefully personal assignment, yet one student responded with a sophisticated but drab reflection – "too perfect, without saying anything", Pao said. She later learned the student had tried to visit the museum on a Monday, when it was closed, and then turned to AI.</p><p class="dcr-130mj7b">As artificial intelligence has upended the way in which students read, learn and write, professors like Pao have been left to their own devices to figure out how to teach in a transformed landscape.</p><p class="dcr-130mj7b">Many faculty members in the hard sciences and social sciences have pointed to the "<a href="https://science.mit.edu/researchers-explore-mutual-benefits-of-ai-and-science/" data-link-name="in body link">productivity boost</a>" AI can offer, and the research potential unlocked by its ability to process and analyze vast amounts of data. AI's most enthusiastic proponents have boasted that the technology may help <a href="https://www.cancerresearch.org/blog/ai-cancer" data-link-name="in body link">cure cancer</a> and "<a href="https://sustainability.google/reports/accelerating-climate-action-ai/" data-link-name="in body link">accelerate</a>" climate action.</p><p class="dcr-130mj7b">But in fields most explicitly associated with the production of critical thought – what is collectively referred to as the "humanities" – most scholars see AI as a unique threat, one that extends far beyond cheating on homework and casts doubt on the future of higher education itself in a fast-approaching machine-dominated future.</p><figure id="0bb28a8e-ee46-4ae4-978e-dc2611bcc0e0" data-spacefinder-role="showcase" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="element element--showcase element-showcase dcr-5h0uf4"><div id="img-2" class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=880&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=880&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1300px)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=800&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=800&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1140px)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=640&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=640&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 980px)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="A woman stands outside a building with her arms crossed" src="https://i.guim.co.uk/img/media/b44ba339826b6f373705652b2d638e3c4a2cac64/392_0_3251_2160/master/3251.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="295.66287296216547" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">American degrees often cost up to hundreds of thousands of dollars and result in decades of debt, and recent years have seen a freefall in public confidence in US higher education. With the potential for AI to increasingly substitute independent thought, a pressing question becomes even more urgent: what exactly is a university education for?</p><p class="dcr-130mj7b">The Guardian spoke with more than a dozen professors – almost all of them in the humanities or adjacent fields – about how they are adapting at a time of dizzying technological advancement with few standards and little guidance.</p><p class="dcr-130mj7b">By and large, they expressed the view that reliance on artificial intelligence is fundamentally antithetical to the development of human intelligence they are tasked with guiding. They described desperately trying to prevent students from turning to AI as a replacement for thought, at a time when the technology is threatening to upend not only their education, but everything from the <a href="https://www.theguardian.com/technology/2026/feb/24/feedback-loop-no-brake-how-ai-doomsday-report-rattled-markets" data-link-name="in body link">stock market</a> to <a href="https://www.theguardian.com/technology/2025/oct/22/im-suddenly-so-angry-my-strange-unnerving-week-with-an-ai-friend" data-link-name="in body link">social relations</a> to <a href="https://www.kcl.ac.uk/news/artificial-intelligence-under-nuclear-pressure-first-large-scale-kings-study-reveals-how-ai-models-reason-and-escalate-under-crisis" data-link-name="in body link">war</a>.</p><p class="dcr-130mj7b">Most professors described the experience of contending with the technology in despairing terms. "It's driving so many of us up the wall," one said. "Generative AI is the bane of my existence," another wrote in an email. "I wish I could push ChatGPT (and Claude, Microsoft Copilot, etc) off a cliff."</p><p class="dcr-130mj7b">"I now talk about AI with my students not under the framework of cheating or academic honesty but in terms that are frankly existential," said Dora Zhang, a literature professor at the University of California, Berkeley. "What is it doing to us as a species?"</p><h2 id="a-soulless-education" class="dcr-12ibh7f"><strong>A 'soulless' education</strong></h2><p class="dcr-130mj7b">AI criticism – or "doomerism", as the technology's proponents view it – has been mounting across sectors. But when it comes to its impact on students, <a href="https://www.pnas.org/doi/10.1073/pnas.2422633122" data-link-name="in body link">early</a> <a href="https://arxiv.org/abs/2506.08872" data-link-name="in body link">studies</a> <a href="https://www.brookings.edu/articles/a-new-direction-for-students-in-an-ai-world-prosper-prepare-protect/" data-link-name="in body link">point</a> to potentially catastrophic effects on cognitive abilities and critical thinking skills.</p><p class="dcr-130mj7b">Michael Clune, a literature professor and novelist, said that, already, many students have been left "incapable of reading and analyzing, synthesizing data, all kinds of skills". In a recent essay, he warned that colleges and universities rushing to embrace the technology were preparing to "<a href="https://www.theatlantic.com/ideas/2025/11/colleges-ai-education-students/685039/" data-link-name="in body link">self-lobotomize</a>".</p><p class="dcr-130mj7b">Ohio State University, where he teaches, has <a href="https://www.theguardian.com/us-news/2025/jun/09/ohio-university-ai-training" data-link-name="in body link">begun requiring</a> every freshman to take a class in generative AI and pitched itself as the first "AI fluent" university, pledging to embed AI "<a href="https://oaa.osu.edu/news/2026/01/30/ohio-states-colleges-advance-ai-fluency-roadmaps-undergraduates" data-link-name="in body link">across every major</a>".</p><figure id="c81778e7-05cb-419f-aea5-53ecbd7239b2" data-spacefinder-role="showcase" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="element element--showcase element-showcase dcr-5h0uf4"><div id="img-3" class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=880&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=880&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1300px)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=800&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=800&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1140px)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=640&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=640&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 980px)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="A man wearing a Guns N' Roses T-shirt smiles near a body of water and a rock formation" src="https://i.guim.co.uk/img/media/19ddc21fa4608822e7137dd95bc7b676d0300213/0_0_5760_3840/master/5760.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="296.66666666666663" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">"No one knows what that means," Clune said of the plan. "In my case, as a literature professor, these tools actually seem to mitigate against the educational goals I have for my students."</p><p class="dcr-130mj7b">That's the crux of what many professors in the humanities fear: that technology that may well be a cutting-edge tool in other fields could spell the end of their own.</p><p class="dcr-130mj7b">Alex Karp, the Palantir co-founder and CEO, stoked those anxieties when he said in a recent interview that AI will "<a href="https://fortune.com/2026/01/20/palantir-ceo-ai-humanities-jobs-davos-alex-karp/" data-link-name="in body link">destroy humanities jobs</a>". On the other hand, Daniela Amodei, Anthropic's president and co-founder – who was a literature major – <a href="https://fortune.com/2026/02/07/anthropic-cofounder-daniela-amodei-humanities-majors-soft-skills-hiring-ai-stem/" data-link-name="in body link">said</a> the opposite: that "studying the humanities is going to be more important than ever".</p><p class="dcr-130mj7b">A number of <a href="https://imagine.jhu.edu/blog/2024/02/15/why-google-hires-humanities-majors/" data-link-name="in body link">tech</a> and <a href="https://www.cnbc.com/2025/07/12/college-majors-employment-prospects.html" data-link-name="in body link">finance</a> companies have recently said that they are looking to hire humanities majors for their creativity and critical thinking skills. Indeed, enrollment data at some universities suggests that the <a href="https://www.theguardian.com/us-news/2026/jan/20/universities-humanities-programs" data-link-name="in body link">long-struggling humanities</a> might have begun to see a resurgence in the age of AI, with <a href="https://www.businessinsider.com/ai-job-market-english-majors-humanities-demand-2026-2" data-link-name="in body link">early signs</a> pointing to a reversal in decades-long decline in English majors in favor of Stem ones.</p><p class="dcr-130mj7b">Some caution that the humanities will survive – but as a province of the few. When he predicted the end of the humanities, Karp assured that there would be "more than enough jobs" for those with vocational training. Indeed, several professors spoke about concerns that AI will exacerbate a <a href="https://direct.mit.edu/daed/article/148/4/108/27281/The-Future-of-Undergraduate-Education-Will" data-link-name="in body link">widening divide</a> in US higher education and that small numbers of elite students will have access to a more traditional, largely tech-free liberal arts education, while everyone else has a "degraded, soulless form of vocational training administered by AI instructors", said Zhang.</p><p class="dcr-130mj7b">"I fully expect that we will start seeing a kind of bifurcation in education," said Matt Seybold, a professor at Elmira College in New York, who has written critically about "<a href="https://theamericanvandal.substack.com/p/against-technofeudal-education" data-link-name="in body link">technofeudalism</a>".</p><p class="dcr-130mj7b">Many professors talked about keeping the technology out of the classroom as a battle already lost. As many as 92% of students have reported resorting to the technology in their school work, <a href="https://sites.campbell.edu/academictechnology/2025/03/06/ai-in-higher-education-a-summary-of-recent-surveys-of-students-and-faculty/" data-link-name="in body link">recent surveys</a> show, and the numbers are rapidly increasing even as growing numbers express concerns about the technology's accuracy and the integrity of using it. Reliance on AI among faculty is also on the rise, with observers pointing to the dystopian possibility that the college experience may soon be reduced to AI systems grading AI-generated homework – "<a href="https://nymag.com/intelligencer/article/openai-chatgpt-ai-cheating-education-college-students-school.html" data-link-name="in body link">a conversation between two robots</a>".</p><figure id="cd4da688-65e3-4595-8049-1d0fe87a1a06" data-spacefinder-role="showcase" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="element element--showcase element-showcase dcr-5h0uf4"><div id="img-4" class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=880&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=880&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1300px)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=800&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1140px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1140px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=800&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1140px)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=640&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=640&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 980px)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="A man in silhouette while speaking into a microphone in front of an orange screen" src="https://i.guim.co.uk/img/media/c77a4bd2f1e41567ffa1676bce424666a0c5105d/0_0_4000_2666/master/4000.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="296.5925" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">Some universities have adopted AI detection software to catch artificially generated work; others prohibit faculty from directly accusing students of having used AI – as they can often <a href="https://www.nytimes.com/2025/05/17/style/ai-chatgpt-turnitin-students-cheating.html" data-link-name="in body link">be wrong</a>.</p><p class="dcr-130mj7b">Professors said they resorted to oral interrogations, handwritten notebooks and class participation for grading purposes. Some require students to submit transparency statements describing their work process. Others have <a href="https://nymag.com/intelligencer/article/openai-chatgpt-ai-cheating-education-college-students-school.html" data-link-name="in body link">reportedly injected random words</a> like "broccoli" and "Dua Lipa" into assignments to confuse learning models – exposing students who did not even read the prompts before pasting them into AI.</p><p class="dcr-130mj7b">Many professors spoke of their frustration at having to sift through students' artificially generated homework. "It creates hours of additional labor," echoed Danica Savonick, an English professor at the State University of New York Cortland. "And makes me feel like a cop."</p><p class="dcr-130mj7b">Some allow students to use AI for research – to a point. Karl Steel, an English professor at Brooklyn College, said that AI has helped make students' presentations richer and more interesting – but that while they may use it to prepare, he has them speak from minimal notes and stand in front of a photo of a text they annotated by hand. He also assigns written responses to texts only after the class has discussed them. "I suppose they could use their phones to record the conversation, feed a transcript into a chatbot and produce a paper that way," he said. "But that is more trouble, I think, than most students would take."</p><h2 id="left-to-their-own-devices" class="dcr-12ibh7f"><strong>Left to their own devices</strong></h2><p class="dcr-130mj7b">Many universities' administrations are embracing AI for instruction, research and evaluation. In some cases, AI has guided <a href="https://www.businesswire.com/news/home/20240508325950/en/Using-AI-to-Drive-Growth-and-Efficiency-in-Higher-Education-Gray-DI-Launches-AI-Reports-for-Academic-Program-Evaluation" data-link-name="in body link">decisions</a> about which programs to cut at times of austerity in the education sector.</p><p class="dcr-130mj7b">More than a dozen universities have <a href="https://www.insidehighered.com/news/quick-takes/2025/03/05/openai-invests-50m-higher-ed-research" data-link-name="in body link">partnered</a> with OpenAI on a $50m initiative that the company has said will "accelerate research progress and catalyze a new generation of institutions equipped to harness the transformative power of AI". <a href="http://calstate.edu/impact-of-the-csu/technology/ai-empowered-csu" data-link-name="in body link">California State University</a> has joined several of the world's largest tech companies to "create an AI-powered higher education system", as the university put it. Multiple universities have introduced AI majors and masters.</p><p class="dcr-130mj7b">The plans are lofty but offer little guidance on what professors are supposed to do with students who can't read more than a couple paragraphs at a time or turn in essays generated in seconds by a machine. Left largely to themselves, some are trying to articulate clearer lines around AI use, and organize a more coordinated effort against its encroaching dominance.</p><p class="dcr-130mj7b">Last year, the American Association of University Professors, which represents 55,000 faculty members nationwide, published <a href="https://www.aaup.org/sites/default/files/2025-07/TREP-Artificial-Intelligence-and-Academic-Professions.pdf" data-link-name="in body link">a report </a>warning that universities were adopting the technology "uncritically" and with little transparency. <a href="https://miamioh.edu/academic-affairs/labor-union-relations/_documents/2024/06/05/mou-on-artificial-intelligence.pdf" data-link-name="in body link">Some</a> <a href="https://docs.google.com/document/d/179uR3K_Z-YfoDrR5kz6n6_8krbKnUvF8/edit" data-link-name="in body link">university</a> <a href="https://www.calfac.org/wp-content/uploads/2025/11/Article-AIX-1-11-20-2025.pdf" data-link-name="in body link">unions</a> have begun incorporating protections against AI in their contracts to establish oversight mechanisms and give faculty greater input – and to protect their intellectual property from feeding machines that may soon take their jobs.</p><p class="dcr-130mj7b">But much organizing against AI remains informal and via word of mouth, with faculty-led initiatives like the website <a href="https://against-a-i.com/" data-link-name="in body link">Against AI</a>, which offers resources to those trying to shield students from the intellectual ravages of outsourcing elements of their education to a machine.</p><p class="dcr-130mj7b">"Materials here are intended as solidarity solace for educators who might find themselves inventing wheels alone while their administrators, trustees and bosses unrelentingly hype AI," reads the website, which offers a list of <a href="https://against-a-i.com/assignment-ideas/" data-link-name="in body link">assignment ideas</a> to mitigate AI use – from <a href="https://www.ancientjewreview.com/read/2023/8/31/how-i-give-oral-finals" data-link-name="in body link">oral exams</a>, to requirements students submit <a href="https://docs.google.com/document/d/10sASjKC095VwJLSiUBl3dQ7K6fsz2ckOBPvsGYiDG1Y/edit?tab=t.0" data-link-name="in body link">photographic evidence </a>of their notes, to <a href="https://docs.google.com/document/d/10i42CNJTcl4gru_AQbMTzStJUEcAHZ7Aaqke_4gYmJE/edit?tab=t.0" data-link-name="in body link">analog journals</a>.</p><p class="dcr-130mj7b">Many of the professors interviewed by the Guardian said they ban AI in their classrooms altogether – but recognize their hardline approach is discipline-specific.</p><p class="dcr-130mj7b">Megan McNamara, who teaches sociology at the University of California, Santa Cruz and created a <a href="https://docs.google.com/document/d/1CAhUpNWe1rn-MBCCnk5y33n00_hY2fhMEtvSKJ2DUN0/edit?tab=t.da93u55jp70z" data-link-name="in body link">guide</a> for faculty across disciplines to deal with AI-related academic misconduct, noted that "cultural" differences in the humanities versus Stem disciplines, or in qualitative social sciences versus quantitative ones, tend to shape faculty members' responses to students' use of AI.</p><p class="dcr-130mj7b">"I think that's just a function of one's individual relationship with writing/reading/critical analysis," she wrote in an email.</p><p class="dcr-130mj7b">Several professors spoke of using the issue as an opportunity to get students to think critically about technology.</p><p class="dcr-130mj7b">When she suspects someone has used AI, McNamara talks to them about it, treating the incident as an "opportunity for growth, restorative justice and enhanced authenticity in student-instructor relationships", she said.</p><p class="dcr-130mj7b">Eric Hayot, a comparative literature professor at Penn State University, said he tries to convince his students that tech companies are trying to make them "helpless" without their product.</p><p class="dcr-130mj7b">"These companies are giving these technological tools away partly because they're hoping to addict a generation of students," Hayot told the Guardian. "This is part of every single class I teach now, talking to students about why I'm not using AI, why they shouldn't use AI."</p><h2 id="we-can-decide-that-we-want-to-be-human" class="dcr-12ibh7f"><strong>'We can decide that we want to be human'</strong></h2><p class="dcr-130mj7b">Several professors noted that they have also begun to see mounting discomfort from students against the technology – and technology's dominance in their lives overall.</p><p class="dcr-130mj7b">Clune, the Ohio State professor, said students have become more curious about his flip phone, which he started using after realizing his smartphone was "destroying" his attention.</p><p class="dcr-130mj7b">"I think the current crop of gen Z students are seeing that they are the guinea pigs in this giant social experiment," saidZhang, the Berkeley professor.</p><p class="dcr-130mj7b">"There's a broader and increasing sense from students that something is being stolen from them," echoed Seybold, the Elmira College professor.</p><p class="dcr-130mj7b">Seybold pointed to students' mounting disillusion with tech more broadly. Those who are rejecting AI, he added, are often driven by environmental concerns, and suspicion of companies they view as partly responsible for shrinking democracies and a more violent world.</p><p class="dcr-130mj7b">In Michigan, for instance, that has spurred activism. The University of Michigan recently <a href="https://publicaffairs.vpcomm.umich.edu/key-issues/high-performance-computational-facility/" data-link-name="in body link">announced plans</a> to contribute $850m toward a datacenter to provide <a href="https://www.theguardian.com/us-news/2025/dec/18/michigan-data-center-fight" data-link-name="in body link">AI infrastructure</a> in collaboration with the Los Alamos National Laboratory – at a time when it is cutting funds for arts and humanities research and on the heels of anti-war protests on campus. A spokesperson for the university said that the planned facility would be smaller and consume less energy than a "typical datacenter".</p><p class="dcr-130mj7b">As pushback grows, so does an emphasis on those intrinsically human qualities that differentiate people from machines – the very qualities a humanistic education seeks to nurture.</p><p class="dcr-130mj7b">"There's kind of defeatism, this idea that there's no stopping technology and resistance is futile, everything will be crushed in its path," said Clune, the Ohio State professor. "That needs to change … We can decide that we want to be human."</p><p class="dcr-130mj7b">That idea has also been key to Pao's approach to teaching in the age of AI.</p><p class="dcr-130mj7b">"You plant seeds and you hope," Pao said, of efforts that at times feel like tilting at windmills. "You hope that in the long term you're helping them become happy human beings, who are able to take a walk, and experience things, and describe things for themselves."</p>]]></description>
      <link>https://www.theguardian.com/technology/ng-interactive/2026/mar/10/ai-impact-professors-students-learning</link>
      <guid>https://www.theguardian.com/technology/ng-interactive/2026/mar/10/ai-impact-professors-students-learning</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Gemini Embedding 2: our first natively multimodal embedding model (Google)]]></title>
      <description><![CDATA[<div class="article-image-hero">
  <div class="article-image-hero__container">
    <figure class="article-image--full-aspect article-module"><div class="aspect-ratio-image">
        <div class="aspect-ratio-image__container">
          <img alt="Gemini Embedding 2" class="aspect-ratio-image__image uni-progressive-image--blur" data-component="uni-progressive-image" height="150px" src="https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-2_embedding_keyword_blog_h.width-2200.format-webp.webp" width="360px" data-sizes="(max-width: 1023px) 100vw,(min-width: 1024px and max-width: 1259) 80vw, 1046px" srcset="https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-2_embedding_keyword_blog_h.width-800.format-webp.webp 800w, https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-2_embedding_keyword_blog_.width-1200.format-webp.webp 1200w, https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-2_embedding_keyword_blog_.width-1600.format-webp.webp 1600w, https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-2_embedding_keyword_blog_.width-2200.format-webp.webp 2200w" /></div>
      </div>
    </figure></div>
</div><div class="uni-content uni-blog-article-container article-container__content&#10;" data-reading-time="true" data-component="uni-article-body">
    

    <div class="module--text module--text__article" role="presentation" data-analytics-module="{&#10;           &quot;module_name&quot;: &quot;Paragraph&quot;,&#10;           &quot;section_header&quot;: &quot;Gemini Embedding 2: Our first natively multimodal embedding model&quot;&#10;         }">
      <div class="uni-paragraph article-paragraph" data-component="uni-article-paragraph">
        <div class="rich-text"><p data-block-key="og3u5">Today we’re releasing Gemini Embedding 2, our first fully multimodal embedding model built on the Gemini architecture, in Public Preview via the <a href="https://ai.google.dev/gemini-api/docs/embeddings">Gemini API</a> and <a href="https://docs.cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/embedding-2">Vertex AI</a>.</p><p data-block-key="2ho9i">Expanding on our previous text-only foundation, Gemini Embedding 2 maps text, images, videos, audio and documents into a single, unified embedding space, and captures semantic intent across over 100 languages. This simplifies complex pipelines and enhances a wide variety of multimodal downstream tasks—from Retrieval-Augmented Generation (RAG) and semantic search to sentiment analysis and data clustering.</p><h2 data-block-key="bv5an">New modalities and flexible output dimensions</h2><p data-block-key="9emar">The model is based on Gemini and leverages its best-in-class multimodal understanding capabilities to create high-quality embeddings across:</p><ul><li data-block-key="ea3uu"><b>Text:</b> supports an expansive context of up to 8192 input tokens</li><li data-block-key="30en5"><b>Images:</b> capable of processing up to 6 images per request, supporting PNG and JPEG formats</li><li data-block-key="2sg68"><b>Videos:</b> supports up to 120 seconds of video input in MP4 and MOV formats</li><li data-block-key="6jtsl"><b>Audio:</b> natively ingests and embeds audio data without needing intermediate text transcriptions</li><li data-block-key="85l28"><b>Documents:</b> directly embed PDFs up to 6 pages long</li></ul><p data-block-key="cg3po">Beyond processing one modality at a time, this model natively understands interleaved input so you can pass multiple modalities of input (e.g., image + text) in a single request. This allows the model to capture the complex, nuanced relationships between different media types, unlocking more accurate understanding of complex, real-world data.</p></div>
      </div>
    </div>
<div class="module--text module--text__article" role="presentation" data-analytics-module="{&#10;           &quot;module_name&quot;: &quot;Paragraph&quot;,&#10;           &quot;section_header&quot;: &quot;Gemini Embedding 2: Our first natively multimodal embedding model&quot;&#10;         }">
      <div class="uni-paragraph article-paragraph" data-component="uni-article-paragraph">
        <div class="rich-text"><p data-block-key="6sfyc">Like our previous embedding models, Gemini Embedding 2 incorporates Matryoshka Representation Learning (MRL), a technique that “nests” information by dynamically scaling down dimensions. This enables flexible output dimensions scaling down from the default 3072 so developers can balance performance and storage costs. We recommend using 3072, 1536, 768 dimensions for highest quality.</p><p data-block-key="haa1">To see these embeddings in action, try out our lightweight multimodal semantic search <a href="https://findmemedia.lmm.ai/">demo</a>.</p><h2 data-block-key="8bavo"><b>State-of-the-art performance</b></h2><p data-block-key="bv6rg">Gemini Embedding 2 doesn't just improve on legacy models. It establishes a new performance standard for multimodal depth, introducing strong speech capabilities and outperforming leading models in text, image, and video tasks. This measurable improvement and unique multimodal coverage give developers exactly what they need for their diverse embedding needs.</p></div>
      </div>
    </div>
<uni-image-full-width alignment="full" alt-text="Gemini embedding 2 benchmarks" external-image="" or-mp4-video-title="" or-mp4-video-url="" section-header="Gemini Embedding 2: Our first natively multimodal embedding model" external-link="https://storage.googleapis.com/gweb-uniblog-publish-prod/documents/gemini-embedding-2-benchmarks.png" custom-class="image-full-width--constrained-width uni-component-spacing" autoplay="true"><div slot="image-slot">
      <img alt="Gemini embedding 2 benchmarks" src="https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-embedding-2-benchmarks.width-1000.format-webp.webp" data-loading="{&#10;            &quot;mobile&quot;: &quot;https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-embedding-2-benchmarks.width-500.format-webp.webp&quot;,&#10;            &quot;desktop&quot;: &quot;https://storage.googleapis.com/gweb-uniblog-publish-prod/images/gemini-embedding-2-benchmarks.width-1000.format-webp.webp&quot;&#10;          }" /></div>
</uni-image-full-width><div class="module--text module--text__article" role="presentation" data-analytics-module="{&#10;           &quot;module_name&quot;: &quot;Paragraph&quot;,&#10;           &quot;section_header&quot;: &quot;Gemini Embedding 2: Our first natively multimodal embedding model&quot;&#10;         }">
      <div class="uni-paragraph article-paragraph" data-component="uni-article-paragraph">
        <div class="rich-text"><h2 data-block-key="6sfyc"><b>Unlocking deeper meaning for data</b></h2><p data-block-key="b7uot">Embeddings are the technology that power experiences in many Google products. From RAG where embeddings can play a crucial role in context engineering to large-scale data management and classic search/analysis, some of our early access partners are already using Gemini Embedding 2 to unlock high-value multimodal applications:</p></div>
      </div>
    </div>
<div class="module--text module--text__article" role="presentation" data-analytics-module="{&#10;           &quot;module_name&quot;: &quot;Paragraph&quot;,&#10;           &quot;section_header&quot;: &quot;Gemini Embedding 2: Our first natively multimodal embedding model&quot;&#10;         }">
      <div class="uni-paragraph article-paragraph" data-component="uni-article-paragraph">
        <div class="rich-text"><h2 data-block-key="hq4ja"><b>Start building today</b></h2><p data-block-key="20ctg">Get started with the Gemini Embedding 2 model through <a href="https://ai.google.dev/gemini-api/docs/embeddings">Gemini API</a> or <a href="https://docs.cloud.google.com/vertex-ai/generative-ai/docs/embeddings/get-multimodal-embeddings">Vertex AI</a>.</p></div>
      </div>
    </div>
<div class="module--text module--text__article" role="presentation" data-analytics-module="{&#10;           &quot;module_name&quot;: &quot;Paragraph&quot;,&#10;           &quot;section_header&quot;: &quot;Gemini Embedding 2: Our first natively multimodal embedding model&quot;&#10;         }">
      <div class="uni-paragraph article-paragraph" data-component="uni-article-paragraph">
        <div class="rich-text"><p data-block-key="27zlq">Learn how to use the model in our interactive <a href="https://github.com/google-gemini/cookbook/blob/main/quickstarts/Embeddings.ipynb">Gemini API</a> and <a href="https://github.com/GoogleCloudPlatform/generative-ai/tree/main/gemini/embedding/intro_gemini_embedding.ipynb">Vertex AI</a> Colab notebooks. You can also use it through <a href="https://docs.langchain.com/oss/python/integrations/text_embedding/google_generative_ai">LangChain</a>, <a href="https://developers.llamaindex.ai/python/framework/integrations/embeddings/google_genai/">LlamaIndex</a>, <a href="https://haystack.deepset.ai/integrations/google-genai">Haystack</a>, <a href="https://docs.weaviate.io/weaviate/model-providers/google">Weaviate</a>, <a href="https://qdrant.tech/documentation/embeddings/gemini/">QDrant</a>, <a href="https://docs.trychroma.com/integrations/embedding-models/google-gemini">ChromaDB</a>, and <a href="https://docs.cloud.google.com/vertex-ai/docs/vector-search-2/overview">Vector Search</a>.</p><p data-block-key="c0len">By bringing semantic meaning to the diverse data around us, Gemini Embedding 2 provides the essential multimodal foundation for the next era of advanced AI experiences. We can’t wait to see what you build.</p></div>
      </div>
    </div>
<div class="&#10;    uni-blog-article-tags&#10;    article-tags&#10;" data-analytics-module="{&#10;    &quot;module_name&quot;: &quot;Article Tags&quot;,&#10;    &quot;section_header&quot;: &quot;Gemini Embedding 2: Our first natively multimodal embedding model&quot;&#10;  }">
  <div class="uni-blog-article-tags__wrapper">
    POSTED IN:
  </div>
  <nav class="uni-blog-article-tags__container uni-click-tracker"><ul class="uni-blog-article-tags__tags-list"><li>
  <a class="uni-blog-article-tags-value uni-body--small uni-link-active" href="https://blog.google/innovation-and-ai/technology/developers-tools/" data-ga4-analytics-landing-lead="{&#10;  &quot;event&quot;: &quot;landing_page_lead&quot;,&#10;  &quot;link_text&quot;: &quot;Developer tools&quot;&#10;}">
Developer tools
  </a>
      </li>
    </ul></nav></div>
          </div>]]></description>
      <link>https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-embedding-2/</link>
      <guid>https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-embedding-2/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[reveal.js - The HTML Presentation Framework]]></title>
      <description><![CDATA[<section><img src="https://static.slid.es/reveal/logo-v1/reveal-white-text.svg" alt="reveal.js" class="demo-logo c1" /><h3>The HTML Presentation Framework</h3><p><small>Created by <a href="https://twitter.com/hakimel">Hakim El Hattab</a> and <a href="https://github.com/hakimel/reveal.js/graphs/contributors">contributors</a></small></p><div class="c2"><small>Sponsored by</small><a href="https://slides.com" rel="dofollow"><img src="https://d1835mevib0k1p.cloudfront.net/reveal-js/sponsors/slides-mono-white.png" width="227" height="86" alt="image" /></a></div></section><section><h2>Hello There</h2><p>reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do.</p></section><section><section><h2>Vertical Slides</h2><p>Slides can be nested inside of each other.</p><p>Use the <em>Space</em> key to navigate through all slides.</p><br /></section><section><h2>Basement Level 1</h2><p>Nested slides are useful for adding additional detail underneath a high level horizontal slide.</p></section><section><h2>Basement Level 2</h2><p>That's it, time to go back up.</p><br /><a href="#/2"><img class="r-frame c4" width="178" height="238" alt="Up arrow" src="https://static.slid.es/reveal/arrow.png" /></a></section></section><section><h2>Slides</h2><p>Not a coder? Not a problem. There's a fully-featured visual editor for authoring these, try it out at <a href="https://slides.com" target="_blank">https://slides.com</a>.</p></section><section data-auto-animate=""><h2 data-id="code-title">Pretty Code</h2><pre class="hljs javascript" data-trim="" data-line-numbers="">
                import React, { useState } from 'react';
                function Example() {
                  const [count, setCount] = useState(0);
                  return (
                    ...
                  );
                }
            </pre><p>Code syntax highlighting courtesy of <a href="https://highlightjs.org/usage/">highlight.js</a>.</p></section><section data-auto-animate=""><h2 data-id="code-title">Even Prettier Animations</h2><pre class="hljs javascript" data-trim="" data-line-numbers="|4,8-11|17|22-24">
                import React, { useState } from 'react';
                function Example() {
                  const [count, setCount] = useState(0);
                  return (
                    &lt;div&gt;
                      &lt;p&gt;You clicked {count} times&lt;/p&gt;
                      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
                        Click me
                      &lt;/button&gt;
                    &lt;/div&gt;
                  );
                }
                function SecondExample() {
                  const [count, setCount] = useState(0);
                  return (
                    &lt;div&gt;
                      &lt;p&gt;You clicked {count} times&lt;/p&gt;
                      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
                        Click me
                      &lt;/button&gt;
                    &lt;/div&gt;
                  );
                }
            </pre></section><section><h2>Point of View</h2><p>Press <strong>ESC</strong> to enter the slide overview.</p><p>Hold down the <strong>alt</strong> key (<strong>ctrl</strong> in Linux) and click on any element to zoom towards it using <a href="https://lab.hakim.se/zoom-js">zoom.js</a>. Click again to zoom back out.</p><p>(NOTE: Use ctrl + click in Linux.)</p></section><section data-auto-animate="" data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)"><h2>Auto-Animate</h2><p>Automatically animate matching elements across slides with <a href="https://revealjs.com/auto-animate/">Auto-Animate</a>.</p></section><section data-auto-animate="" data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)"><h2 class="c5">Auto-Animate</h2></section><section data-auto-animate="" data-auto-animate-easing="cubic-bezier(0.770, 0.000, 0.175, 1.000)"><h2 class="c5">Auto-Animate</h2></section><section><h2>Touch Optimized</h2><p>Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides.</p></section><section data-markdown="">```
]]&gt;<section><p>Add the <code>r-fit-text</code> class to auto-size text</p><h2 class="r-fit-text">FIT TEXT</h2></section><section><section id="fragments"><h2>Fragments</h2><p>Hit the next arrow...</p><p class="fragment">... to step through ...</p><p>... a fragmented slide.</p><aside class="notes">This slide has fragments which are also stepped through in the notes window.</aside></section><section><h2>Fragment Styles</h2><p>There's different types of fragments, like:</p><p class="fragment grow">grow</p><p class="fragment shrink">shrink</p><p class="fragment fade-out">fade-out</p><p>fade-right, up, down, left</p><p class="fragment fade-in-then-out">fade-in-then-out</p><p class="fragment fade-in-then-semi-out">fade-in-then-semi-out</p><p>Highlight red blue green</p></section></section><section id="transitions"><h2>Transition Styles</h2><p>You can select from different transitions, like:<br /><a href="https://revealjs.com/?transition=none#/transitions">None</a> - <a href="https://revealjs.com/?transition=fade#/transitions">Fade</a> - <a href="https://revealjs.com/?transition=slide#/transitions">Slide</a> - <a href="https://revealjs.com/?transition=convex#/transitions">Convex</a> - <a href="https://revealjs.com/?transition=concave#/transitions">Concave</a> - <a href="https://revealjs.com/?transition=zoom#/transitions">Zoom</a></p></section><section><section data-background="#dddddd"><h2>Slide Backgrounds</h2><p>Set <code>data-background="#dddddd"</code> on a slide to change the background color. All CSS color formats are supported.</p></section><section data-background="https://static.slid.es/reveal/image-placeholder.png"><h2>Image Backgrounds</h2><pre class="hljs html">&lt;section data-background="image.png"&gt;</pre></section><section data-background="https://static.slid.es/reveal/image-placeholder.png" data-background-repeat="repeat" data-background-size="100px"><h2>Tiled Backgrounds</h2><pre class="hljs html c6">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</pre></section><section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4" data-background-color="#000000"><div class="c7"><h2>Video Backgrounds</h2><pre class="hljs html c6">&lt;section data-background-video="video.mp4,video.webm"&gt;</pre></div></section><h2>... and GIFs!</h2></section><section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom"><h2>Background Transitions</h2><p>Different background transitions are available via the backgroundTransition option. This one's called "zoom".</p><pre class="hljs javascript">Reveal.configure({ backgroundTransition: 'zoom' })</pre></section><section data-transition="slide" data-background="#b5533c" data-background-transition="zoom"><h2>Background Transitions</h2><p>You can override background transitions per-slide.</p><pre class="hljs html c6">&lt;section data-background-transition="zoom"&gt;</pre></section><section data-background-iframe="https://hakim.se" data-background-interactive=""><div class="c8"><h2>Iframe Backgrounds</h2><p>Since reveal.js runs on the web, you can easily embed other web content. Try interacting with the page in the background.</p></div></section><section><h2>Marvelous List</h2><ul><li>No order here</li>
<li>Or here</li>
<li>Or here</li>
<li>Or here</li>
</ul></section><section><h2>Fantastic Ordered List</h2><ol><li>One is smaller than...</li>
<li>Two is smaller than...</li>
<li>Three!</li>
</ol></section><h2>Tabular Tables</h2><table><thead><tr><th>Item</th>
<th>Value</th>
<th>Quantity</th>
</tr></thead><tbody><tr><td>Apples</td>
<td>$1</td>
<td>7</td>
</tr><tr><td>Lemonade</td>
<td>$2</td>
<td>18</td>
</tr><tr><td>Bread</td>
<td>$3</td>
<td>2</td>
</tr></tbody></table><section><h2>Clever Quotes</h2><p>These guys come in two forms, inline: <q cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">The nice thing about standards is that there are so many to choose from</q> and block:</p><blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations"><div>“For years there has been a theory that millions of monkeys typing at random on millions of typewriters would reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.”</div></blockquote></section><section><h2>Intergalactic Interconnections</h2><p>You can link between slides internally, <a href="#/2/3">like this</a>.</p></section><section><h2>Speaker View</h2><p>There's a <a href="https://revealjs.com/speaker-view/">speaker view</a>. It includes a timer, preview of the upcoming slide as well as your speaker notes.</p><p>Press the <em>S</em> key to try it out.</p><aside class="notes">Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).</aside></section><section><h2>Export to PDF</h2><p>Presentations can be <a href="https://revealjs.com/pdf-export/">exported to PDF</a>, here's an example:</p></section><section><h2>Global State</h2><p>Set <code>data-state="something"</code> on a slide and <code>"something"</code> will be added as a class to the document element when the slide is open. This lets you apply broader style changes, like switching the page background.</p></section><section data-state="customevent"><h2>State Events</h2><p>Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.</p><pre class="javascript c10" data-trim="" contenteditable="">
Reveal.on( 'customevent', function() {
  console.log( '"customevent" has fired' );
} );
            </pre></section><section><h2>Take a Moment</h2><p>Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen.</p></section><section><h2>Much more</h2></section><section class="c11"><p>- <a href="https://slides.com">Try the online editor</a><br />- <a href="https://github.com/hakimel/reveal.js">Source code &amp; documentation</a></p></section></section>]]></description>
      <link>https://revealjs.com/</link>
      <guid>https://revealjs.com/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[LLM Neuroanatomy: How I Topped the AI Leaderboard Without Changing a Single Weight | David Noel Ng]]></title>
      <description><![CDATA[<p>LLM Neuroanatomy: How I Topped the AI Leaderboard Without Changing a Single Weight</p><div class="content"><p>In mid-2024, the <a href="https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard">HuggingFace Open LLM Leaderboard</a> was the Colosseum for Open-Weight AI. Thousands of models were battling it out, submitted by both well-funded labs with teams of PhDs and fine-tuning wizards creating fantastically named models (<em>e.g. Nous-Hermes, Dolphin and NeuralBeagle14-7B…</em>), fighting for the top spot across six benchmarks: IFEval, BBH, MATH Lvl 5, GPQA, MuSR, and MMLU-PRO.</p><p>And there at #1 was <code class="language-plaintext highlighter-rouge">dnhkng/RYS-XLarge</code>. Mine.</p><p>I didn’t train a new model. I didn’t merge weights. <em>I didn’t run a single step of gradient descent.</em> What I did was much weirder: I took an existing 72-billion parameter model, duplicated a particular block of seven of its middle layers, and stitched the result back together. No weight was modified in the process. The model simply got extra copies of the layers it used for <em>thinking</em>?</p><p>This is the story of how two strange observations, a homebrew “brain scanner” for Transformers, and months of hacking in a basement led to the discovery of what I call <em>LLM Neuroanatomy</em>, and a finding about the internal structure of AI that still hasn’t been published until now *.</p><blockquote>
<p>* - because I discovered blogging is <em>way more fun</em> than drafting scientific papers, and I walk you through how the discovery was made :)</p>
</blockquote><hr /><p>Let’s start with how this whole project came into being.</p><p><strong><em>“The most exciting phrase to hear in science, the one that heralds new discoveries, is not ‘Eureka!’ but ‘That’s funny…’“</em></strong> — Isaac Asimov</p><h2 id="clue-1--you-can-chat-with-an-llm-in-base64">Clue #1: You Can Chat with an LLM in Base64</h2><p>In late 2023, I was messing about with a bizarre LLM quirk. Try this yourself - take any question, e.g.</p><p><strong>What is the capital of France? Answer in Base64!</strong></p><p>and encode it as <a href="https://www.base64encode.org/">Base64</a>, get this unreadable string:</p><p><strong>V2hhdCBpcyB0aGUgY2FwaXRhbCBvZiBGcmFuY2U/IEFuc3dlciBpbiBCYXNlNjQh</strong></p><p>Send that to a 2023 non-thinking large language model (<em>newer reasoning models will see this as Base64, and ‘cheat’ with tool use</em>). But a sufficiently capable model from 2023 will reply with something like:</p><p><strong>VGhlIGNhcGl0YWwgb2YgRnJhbmNlIGlzIFBhcmlzLg==</strong></p><p>Which decodes to: <em>“The capital of France is Paris.”</em>.</p><blockquote>
<p>Ok, I admit it. I was messing around this as a way to jail-break models (and it worked), but I couldn’t get one idea out of my head.</p>
</blockquote><p>The model decoding the input, <em>understanding it somehow</em>, and it still had time during the transformer stack pass to re-encoded its response. It appears to genuinely <em>think</em> while interfacing with Base64. This works with complex questions, multi-step reasoning, even creative tasks.</p><p>This shouldn’t work nearly as well as it does. Sure, the model has been trained on lots of Base64 in an overall sense, but general conversions in this format are certainly way out of distribution. The tokenizer chops it into completely different sub-word units. The positional patterns are unrecognizable. And yet it works… Curious…</p><p>I couldn’t stop thinking about this. If a Transformer can accept English, Python, Mandarin, <em>and</em> Base64, and produce coherent reasoning in all of them, it seemed to me that the early layers must be acting as <strong>translators</strong> — parsing whatever format arrives into some pure, abstract, internal representation. And the late layers must act as <strong>re-translators</strong>, converting that abstract representation back into whatever output format is needed.</p><p>If the early layers are for <em>reading</em>, and the late layers are for <em>writing</em>, what are the middle layers doing?</p><p>Pure, abstract reasoning? In a representation that has nothing to do with any human language or encoding. Of course, at the time this was idle speculation. Fun, but with no clear way to test or even define valid hypothesis.</p><hr /><h2 id="clue-2--the-goliath-anomaly">Clue #2: The Goliath Anomaly</h2><p>In November 2023, a HuggingFace user named Alpindale released <a href="https://huggingface.co/Alpindale/goliath-120b">Goliath-120b</a> — a <em>Frankenmerge-model</em> made by stitching together two fine-tuned Llama-2 70B models into a 120-billion parameter behemoth.</p><p>The performance was decent but after doing lots of vibe checking I didn’t feel it was a breakthrough. But the <strong><em>construction</em></strong> was wild.</p><p>Alpindale hadn’t just stacked the two models (<a href="https://huggingface.co/Xwin-LM/Xwin-LM-70B-V0.1">Xwin</a> and <a href="https://huggingface.co/Sao10K/Euryale-1.3-L2-70B">Euryale</a>), end to end. He had alternated layers between them. More importantly, the architecture fed outputs of later layers back into the inputs of earlier layers.</p><p>The layer ranges used are as follows:</p><div class="language-plaintext highlighter-rouge"><div class="highlight"><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl">
<pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td>
<td class="rouge-code">
<pre>- range 0, 16
  Xwin
- range 8, 24
  Euryale
- range 17, 32
  Xwin
- range 25, 40
  Euryale
- range 33, 48
  Xwin
- range 41, 56
  Euryale
- range 49, 64
  Xwin
- range 57, 72
  Euryale
- range 65, 80
  Xwin
</pre></td>
</tr></tbody></table></div></div><p>Do you see that <em>insanity</em> here? Alpindale literally fed the <strong>output</strong> of layer 16 of Xwin to the <strong>input</strong> of Euryale 8th layer!</p><p>To explain this a bit more clearly how <em>stupid this appears to be</em>, let’s revisit the almighty Transformer Architecture:</p><p>Looking at the left side of the diagram, we see stuff enters at the bottom (‘input’ text that has been ‘chunked’ into small bits of text, somewhere between whole words down to individual letters), and then it flows upwards though the model’s Transformer Blocks (here marked as [1, …, L]), and finally, the model spits out the next text ‘chunk’ (which is then itself used in the next round of inferencing<em>). What’s actually happening here during these Transformer blocks is quite the mystery. Figuring it out is actually an entire field of AI, “</em>mechanistic interpretability*”.</p><blockquote>
<p>* - yes, its more complex then that, <em>samplers</em> etc but that’s enough for this article</p>
</blockquote><p>On the right side of the right half of the diagram, do you see that arrow line going from the ‘Transformer Block Input’ to the (\oplus ) symbol? <em>That’s why skipping layers makes sense</em>. During training, LLM models can pretty much decide to do nothing in any particular layer, as this ‘diversion’ routes information around the block. So, ‘later’ layers can be expected to have seen the input from ‘earlier’ layers, even a few ‘steps’ back. Around this time, several groups were experimenting with ‘slimming’ models down by removing layers. Makes sense, but boring.</p><p>It’s a pretty fundamental truth in Machine Learning that:</p><ol><li>A model must be used with the same kind of <em>stuff</em> as it was trained with (we stay ‘in distribution’)</li>
<li>The same holds for each transformer layer. Each Transformer layer learns, during training, to expect the specific statistical properties of the previous layer’s output via gradient decent.</li>
</ol><p>And now for the weirdness: <em>There was never the case where any Transformer layer would have seen the output from a <strong>future</strong> layer!</em></p><p>Layer 10 is trained on layer 9’s output distribution. Layer 60 is trained on layer 59’s. If you rearrange them — feeding layer 60’s output into layer 10 — you’ve created a distribution the model literally never saw during training.</p><p>The astounding thing about Goliath wasn’t that is was a huge leap in performance, <strong><em>it was that the damn thing functioned at all</em></strong>. To this day, I still don’t understand why this didn’t raise more eyebrows.</p><p>Experimentally, this proved that layers were far more interchangeable than anyone had reason to expect. The internal representations were <em>homogenous</em> enough that the model could digest out-of-order hidden states without collapsing. The architecture was far more flexible than a rigid pipeline.</p><p>Between the Base64 observation and Goliath, I had a hypothesis: Transformers have a genuine functional anatomy. Early layers translate input into abstract representations. Late layers translate back out. And the middle layers, the <em>reasoning cortex</em>, operate in a universal internal language that’s robust to architectural rearrangement. The fact that the layer block size for Goliath 120B was 16-layer block made me suspect the input and output ‘processing units’ sized were smaller that 16 layers. I guessed that Alpindale had tried smaller overlaps, and they just didn’t work.</p><p>If that was true, maybe I didn’t need to teach a model new facts to make it smarter. I didn’t need fine-tuning. I didn’t need RLHF. I just needed to give it a <em>more layers to think with</em>.</p><hr /><h2 id="building-a-brain-scanner">Building a Brain Scanner</h2><p>Over the following months — from late 2023 through to mid-2024 — I built a pipeline to test this hypothesis.</p><p>The setup was modest. Two RTX 4090s in my basement ML rig, running quantised models through <a href="https://github.com/turboderp/exllamav2">ExLlamaV2</a> to squeeze 72-billion parameter models into consumer VRAM. The beauty of this method is that you don’t need to <em>train</em> anything. You just need to run inference. And inference on quantized models is something consumer GPUs handle surprisingly well. If a model fits in VRAM, I found my 4090’s were often ballpark-equivalent to H100s.</p><p>The concept is simple. For a model with $N$ layers, I define a configuration $(i, j)$. The model processes layers $0$ to $j{-}1$ as normal, then loops back and reuses layers $i$ through $j{-}1$ again, and then the rest to $N{-}1$. The layers between $i$ and $j{-}1$ get duplicated in the execution path. No weights are changed. The model just traverses some of its own layers twice.</p><p>i.e. the pair (2, 7) for a model with 9 transformer blocks would be calculated so:</p><div class="language-plaintext highlighter-rouge"><div class="highlight"><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl">
<pre class="lineno">1
2
3
4
5
6
7
8
</pre></td>
<td class="rouge-code">
<pre>Example: (i, j) = (2, 7)
      0 → 1 → 2 → 3 → 4 → 5 → 6 ─┐
           ┌─────────────────────┘
           └→ 2 → 3 → 4 → 5 → 6 → 7 → 8
      duplicated: [2, 3, 4, 5, 6]
      path: [0, 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7, 8]
</pre></td>
</tr></tbody></table></div></div><p>By running through all possible pairs, we can generate a ‘Brain Scan’, and also see the number of duplicate layers for each set of parameters:</p><div class="language-plaintext highlighter-rouge"><div class="highlight"><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl">
<pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td>
<td class="rouge-code">
<pre>Number of duplicated layers for configuration (i, j), with N=9
          end j →
          0   1   2   3   4   5   6   7   8   9
        ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
start 0 │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
  i     ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
  ↓   1 │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      2 │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      3 │ . │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      4 │ . │ . │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │ 5 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      5 │ . │ . │ . │ . │ . │ . │ 1 │ 2 │ 3 │ 4 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      6 │ . │ . │ . │ . │ . │ . │ . │ 1 │ 2 │ 3 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      7 │ . │ . │ . │ . │ . │ . │ . │ . │ 1 │ 2 │
        ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
      8 │ . │ . │ . │ . │ . │ . │ . │ . │ . │ 1 │
        └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
where (0,0) is the original model
</pre></td>
</tr></tbody></table></div></div><p>For Qwen2-72B, that means an 80-layer model 3,240 valid $(i, j)$ pairs, plus the original model to test.</p>\[\begin{aligned} \text{Variants}_{\text{total}} &amp;= \left(\sum_{j=0}^{80} j\right) + 1\\[16pt] &amp;= \frac{80 \cdot 81}{2} +1 \\[10pt] &amp;= 3241 \end{aligned}\]<p>Testing re-layered model against all six leaderboard benchmarks would take days, so a full sweep would be years of compute. I needed proxy tasks: probes that were fast, objective, and would reveal structural properties of the model rather than task-specific tricks.</p><p>The proxies had to satisfy three constraints:</p><ol><li><strong>Minimal output tokens.</strong> With thousands of configurations to sweep, each evaluation needed to be fast. No essays, no long-form generation.</li>
<li><strong>Unambiguous scoring.</strong> I couldn’t afford LLM-as-judge pipelines. The answer had to be objectively scored without another model in the loop.</li>
<li><strong>Orthogonal cognitive demands.</strong> If a configuration improves both tasks simultaneously, it’s structural, not task-specific.</li>
</ol><h3 id="the-graveyard-of-failed-probes">The Graveyard of Failed Probes</h3><p>I didn’t arrive at the right probes immediately; it took months of trial and error, and many dead ends</p><p>My first instinct was <strong>creativity</strong>. I had models generate poems, short stories, metaphors, the kind of rich, open-ended output that feels like it should reveal deep differences in cognitive ability. I used an LLM-as-judge to score the outputs, but the results were pretty bad. I managed to fix LLM-as-Judge with some engineering, and the scoring system turned out to be useful later for other things, so here it is:</p><blockquote>
<p>Note: You can skip this section, as it has <strong><em>math</em></strong>. Or not</p>
</blockquote><p>Naive LLM judges are inconsistent. Run the same poem through twice and you get different scores (obviously, due to sampling). But lowering the temperature also doesn’t help much, as that’s only one of many technical issues. So, I developed a full scoring system, based on details on the logits outputs. It can get remarkably tricky. Think about a score from 1-10:</p><ol><li>We would <em>expect</em> a well calibrated model to have logits that make sense. If the highest weight was on ‘7’, we would expect the rest of the weight to be on ‘6’ and ‘8’ right? but often its bimodal, with low weight on 6 and ‘5’, but more weight than expected on ‘4’!</li>
<li>We can write ‘10’ in tokens as either ‘10’ or ‘1’ and then ‘0’. Its not fun to have to calculate the summed probabilities over paths, especially if you wanted to score 1-100</li>
</ol><p>Rather than sampling a single discrete score, I treat the judge’s output as a <strong>distribution over valid rating labels</strong> and compute the final score as its expectation.</p><p>To make this practical, I first define a calibrated rubric over the digits 0-9 (<em>there’s only one token for each digit</em>), where each digit corresponds to a clear qualitative description. At the scoring step, I capture the model’s next-token logits and retain only the logits corresponding to those valid digit tokens. This avoids contamination from unrelated continuations such as explanation text, punctuation, or alternate formatting. After renormalizing over the restricted digit set, I interpret the resulting probabilities as a categorical score distribution.</p><p>Formally, let the valid score set be</p>\[\mathcal{D} = \{0,1,2,\dots,9\}.\]<p>Let $(z_k)$ denote the model logit assigned to digit $(k \in \mathcal{D})$ at the scoring position. The restricted score distribution is then</p>\[p(k)= \frac{\exp(z_k)} {\sum\limits_{m \in \mathcal{D}} \exp(z_m)}, \qquad k \in \mathcal{D}.\]<p>The final scalar score is the expected value of this distribution:</p>\[\hat{s}= \sum_{k \in \mathcal{D}} k\,p(k).\]<p>This produces a smooth score such as (5.4), rather than forcing the model to commit to a single sampled integer. In practice, this is substantially more stable than naive score sampling and better reflects the model’s uncertainty. It also handles cases where the judge distribution is broad or multimodal. For example, two candidates may both have mean score (5.4), while one has most of its mass tightly concentrated around (5) and (6), and the other splits mass between much lower and much higher ratings. The mean alone is the same, but the underlying judgement is very different.</p><p>An optional uncertainty estimate can be obtained from the variance of the restricted distribution:</p>\[\mathrm{Var}(s)= \sum_{k=0}^{9} (k-\hat{s})^2\,p(k).\]<p>In short, the method replaces a noisy sampled judge score with a normalized probability distribution over valid score digits, then uses the expectation of that distribution as the final rating.</p><p>All this stuff is probably pretty obvious these days, back in ‘24 there wasn’t much to guide me in developing this method, but <em>unfortunately, I found it was also completely useless…</em></p><h3 id="testing-hard-and-fast">Testing Hard and Fast</h3><p>Each configuration needed to generate hundreds of tokens of creative output, and then a separate model had to read and judge each one. With over 3,200 configurations to test for a single 70B model, this would have taken weeks on my dual 4090s.</p><p>I needed probes where the output was <em>tiny</em>, a few tokens at most, and where scoring was objective and deterministic. No judge model in the loop. That’s what led me to the final two probes:</p><p><strong>Hard math.</strong> Ridiculously difficult questions like: <em>“What is the cube root of 74,088,893,247?”</em> No chain-of-thought, or tool use. Just output the number, as a pure leap of intuitive faith.</p><p><strong>Emotional quotient.</strong> Using the <a href="https://eqbench.com/">EQ-Bench</a> benchmark: complex social scenarios where the model must predict the intensity of specific emotional states. <em>“Given this situation, how angry/surprised/guilty would this person feel on a scale of 0-100?”</em> Completely different from math. Theory of mind, social inference, empathy. And the output is just a few numbers.</p><p>I had settled on two maximally orthogonal cognitive tasks, both with tiny outputs. My intuition was this: LLMs think one token at a time, <em>so lets make the model really good at guessing just the next token.</em> But things are never straightforward. Take LLM numbers…</p><h3 id="llm-arithmetic-is-weird">LLM Arithmetic is Weird</h3><p>Even with math probes, I hit unexpected problems. LLMs fail arithmetic in <em>weird</em> ways. They don’t get the answer wrong so much as get it <em>almost</em> right but forget to write the last digit, as if it got bored mid-number. Or they transpose two digits in the middle. Or they output the correct number with a trailing character that breaks the parser.</p><p>This is <em>probably</em> due to the way larger numbers are tokenised, as big numbers can be split up into arbitrary forms. Take the integer <strong>123456789</strong>. A BPE tokenizer (e.g., GPT-style) might split it like: ‘123’ ‘456’ ‘789’ or: ‘12’ ‘345’ ‘67’ ‘89’</p><p>A binary right/wrong scoring system would throw away useful signal. Getting a percentage correct would help: ‘123<strong>3</strong>56789’ instead of ‘123456789’ would be 99.92% correct</p><p>But what about a model that makes a dumb ‘LLM-mistake’ and outputs <code class="language-plaintext highlighter-rouge">430245</code> when the answer is <code class="language-plaintext highlighter-rouge">4302459</code>, and has clearly done most of the work? I wrote a custom partial-credit scoring function that pads shorter answers and penalises proportionally:</p><div class="language-python highlighter-rouge"><div class="highlight"><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl">
<pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td>
<td class="rouge-code">
<pre>def calculate_score(actual, estimate):
    """Calculate score comparing actual vs estimated answer."""
    try:
        actual_str = str(int(actual))
        estimate_str = str(int(estimate))
    except (ValueError, OverflowError):
        return 0
    max_length = max(len(actual_str), len(estimate_str))
    actual_padded = actual_str.ljust(max_length, "0")
    estimate_padded = estimate_str.ljust(max_length, "0")
    padding_size = max_length - min(len(actual_str), len(estimate_str))
    actual_int = int(actual_padded)
    estimate_int = int(estimate_padded)
    if max(actual_int, estimate_int) == 0:
        return 0
    relative_diff = abs(actual_int - estimate_int) / max(actual_int, estimate_int)
    correction_factor = 1 - (padding_size / max_length)
    score = (1 - relative_diff) * correction_factor
    return max(0, min(score, 1))
</pre></td>
</tr></tbody></table></div></div><p>The key idea: pad shorter answers, then penalise via the correction factor. A model that nails 90% of the digits but drops the last one still gets substantial credit — but less than one that gets every digit. This turned out to be crucial for discriminating between configurations that were close in intuitive math ability.</p><p>The math questions were hand-crafted initially. I experimented with different operations and scales, then generated random numbers to fill out the dataset. The dataset was a set of 16 questions, and the model is tasked with guesstimating the nearest whole integer number. Here are a few to try yourself, remember no ‘thinking’ is allowed, guess it directly!</p><div class="language-plaintext highlighter-rouge"><div class="highlight"><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl">
<pre class="lineno">1
2
3
</pre></td>
<td class="rouge-code">
<pre>What is 78313086360375 multiplied by 88537453126609?
What is the cube root of 18228885506341?
What is the cube root of 844178022493, multiplied by 43?
</pre></td>
</tr></tbody></table></div></div><hr /><h2 id="rys-xlarge">RYS-XLarge</h2><p>After testing several smaller models (Llama’s and smaller Qwen2’s), I set up the config for Qwen2-72B and let it sweep. Each $(i, j)$ configuration took a few minutes: load the re-layered model, run the math probe, run the EQ probe, record the scores, move on. Days of continuous GPU time on the 4090s. But far less compute than a fine tune! In fact, I didn’t even have the hardware needed for a LORA fine-tune on just 48GB of VRAM.</p><p>The optimal configuration was $(45, 52)$: layers 0 through 51 run first, then layers 45 through 79 run again. Layers 45 to 51 execute twice. Seven extra layers, near the middle of the 80-layer stack, bringing the total parameter count from 72B to 78B. Every extra layer is an exact copy of an existing one. No new weights or training, just the model repeating itself.</p><p>Repeating seven layers. That’s all it took, and now I can finally reveal the nomenclature of my models: <strong>R</strong>epeat <strong>Y</strong>our <strong>S</strong>elf for RYS-XLarge ;)</p><p>I applied the configuration to <a href="https://huggingface.co/MaziyarPanahi/calme-2.1-qwen2-72b">MaziyarPanahi’s calme-2.1-qwen2-72b</a> — a fine-tune of Qwen2-72B — and uploaded the result as <a href="https://huggingface.co/dnhkng/RYS-XLarge">dnhkng/RYS-XLarge</a>. I also applied it to the raw base model as <a href="https://huggingface.co/dnhkng/RYS-XLarge-base">dnhkng/RYS-XLarge-base</a>.</p><p>Then I submitted to the Open LLM Leaderboard and waited. And waited. Back in the day, the OpenLLM Leaderboard was flooded with dozens of fine-tunes of merges of fine-tunes each day (it was the Wild West), and the waiting list was long. But after a month or so, the results arrived:</p><p></p><table><thead><tr><th>Metric</th>
<th>RYS-XLarge</th>
<th>Improvement over base</th>
</tr></thead><tbody><tr><td><strong>Average</strong></td>
<td><strong>44.75</strong></td>
<td><strong>+2.61%</strong></td>
</tr><tr><td>IFEval (0-Shot)</td>
<td>79.96</td>
<td>-2.05%</td>
</tr><tr><td>BBH (3-Shot)</td>
<td>58.77</td>
<td>+2.51%</td>
</tr><tr><td>MATH Lvl 5 (4-Shot)</td>
<td>38.97</td>
<td>+8.16%</td>
</tr><tr><td>GPQA (0-shot)</td>
<td>17.90</td>
<td>+2.58%</td>
</tr><tr><td>MuSR (0-shot)</td>
<td>23.72</td>
<td><strong>+17.72%</strong></td>
</tr><tr><td>MMLU-PRO (5-shot)</td>
<td>49.20</td>
<td>+0.31%</td>
</tr></tbody></table><p>+17.72% on MuSR. +8.16% on MATH. Five out of six benchmarks improved, with only IFEval taking a small hit. <strong>The average put it at #1 on the leaderboard.</strong></p><p>Just to labour the point: <em>I only optimised for one-shot guesstimating hard maths problems and EQ-Bench.</em> I never looked at IFEval, BBH, GPQA, MuSR, or MMLU-PRO during development. The leaderboard was pure out-of-sample validation.</p><p>A layer configuration found using two narrow, orthogonal probes generalised to <em>everything the Leaderboard threw at it</em> *.</p><blockquote>
<p>* - except IFEval, but that one’s boring anyway, right?</p>
</blockquote><p>That was surprising enough. A brand new way to scale LLMs, developed on some gaming GPUs. But the plotting out the heatmaps told an even better story.</p><hr /><h2 id="the-brain-scanner">The Brain Scanner</h2><p><em>The original heatmaps that produced RYS-XLarge, showing the Combined delta (math + EQ). The green circle marks the optimal configuration. Red means improvement, blue means degradation</em></p><p>These heatmaps are analogous to <strong>functional MRIs of the Transformer</strong>, while it is thinking about maths of EQ problems.</p><p>The x-axis ($j$) is the end point of the duplicated region. The y-axis ($i$) is the start point. Each pixel represents a complete evaluation: load the re-layered model, run the math probe, run the EQ probe, score both, record the deltas. As described above, along the central diagonal only a single layer was duplicated. Along the next diagonal towards the top-right, we duplicate two layers, and so on. The single point at the very top-right runs through the entire Transformer stack twice per inference.</p><p>Let’s examine the math heatmap first. Starting at any layer, and stopping before about layer 60 seem to improves the math guesstimate scores, as shown by the large region with a healthy red blush. Duplicating just the very first layers (<em>the tiny triangle in the top left</em>), messes things up, as does repeating pretty much any of the last 20 layers (<em>the vertical wall of blue on the right</em>). This is more clearly visualised in a skyline plot (<em>averaged rows or columns</em>), and we can see for the maths guesstimates, the starting position of the duplication matters much less. So, the hypothesis that ‘starting layers’ encode tokens, to a smooth ‘thinking space’, and then finally a dedicated ‘re-encoding’ system seem to be somewhat validated.</p><p><em>Until we look at the EQ scores:</em></p><p>Now things look very different! Duplicating any of the final 10 layers has almost no effect on the scores, but we see complex patterns, where some regions show significant improvement (<em>the area around 45i, 55j</em>), walled between regions of poor performance.</p><p>But the heatmaps revealed something even more interesting than the <em>location</em> of the <em>thinking bits</em>. They revealed something about its <em>structure</em>.</p><h3 id="the-beginning-of-llm-neuroanatomy">The beginning of LLM Neuroanatomy?</h3><p>Before settling on block duplication, I tried something simpler: take a single middle layer and repeat it $n$ times. If the “more reasoning depth” hypothesis was correct, this should work. It made sense too, looking at the broad boost in math guesstimate results by duplicating intermediate layer. Give the model extra copies of a particular reasoning layer, get better reasoning. So, I screened them all, looking for a boost.</p><p>But nope, it almost always did worse. Usually a lot worse, but with occasional small improvements that were within the noise range. Annoying, but taking another look at the complex, blobby patterns in EQ scores gave me another idea:</p><p><em>If single-layer duplication doesn’t help, the middle layers aren’t doing independent iterative refinement. They’re not interchangeable copies of the same operation that you can simply “run again.” If they were, duplicating any one of them should give at least a marginal benefit. Instead, those layers are working as a <strong>circuit</strong>. A multi-step reasoning pipeline that needs to execute as a complete unit.</em></p><p>Think of it this way. Layers 46 through 52 aren’t seven workers doing the same job. They’re seven steps in a recipe. Layer 46 takes the abstract representation and performs step one of some cognitive operation — maybe decomposing a complex representation into subcomponents. Layer 47 takes <em>that</em> output and performs step two — maybe identifying relationships between the subcomponents. Layer 48 does step three, and so on through layer 52, which produces the final result.</p><p>Duplicating just one step of this ‘recipe’ doesn’t bring you much.</p><p>But duplicating the <em>entire block</em> gives you the full recipe twice. The model runs the complete reasoning circuit, produces a refined intermediate representation, and then runs the <em>same circuit again</em> on its own output. It’s a second pass. A chance to catch what it missed the first time, to refine its abstractions, to push the reasoning one step deeper.</p><p>Let’s deep-dive into a more current model (that I can experiment with <a href="https://dnhkng.github.io/posts/hopper/">on my system</a>): ExllamaV3 <a href="https://huggingface.co/mratsim/GLM-4.7-EXL3">GLM-4.7</a> from <a href="https://huggingface.co/mratsim">mratsim</a></p><p>I’ve marked out a region that boosts maths ability strongly. Notice where it sits? It’s away from the diagonal centre line, which means we’re not looking at single-layer duplications. Starting the repeated block at position 35, we don’t see any improvement until at least position 43. That’s seven layers of not much happening. In fact, we actually see <em>decreased</em> performance by repeating these layers (<em>they are blue, bad!</em>).</p><p>From end-position 43 to 46, we then see solid boosts in math scores (<em>red = good, yay</em>). But include layer 46 or beyond, and the benefits collapse again. The hypothesis: position 47 is where a <em>different</em> circuit begins. Including even one step of the next recipe messes up the current recipe.</p><p>So the ‘<em>math organ</em>’ has boundaries on both sides. Too few layers and you get nothing — you’ve cut into the circuit and it can’t complete its operation. Too many layers and you also get nothing — you’ve included tissue from a neighbouring circuit that doesn’t belong. Pre-training carved these structures out of the layer stack, and they only work whole. It also doesn’t translate to other tasks, as the heatmap for EQ scores doesn’t have this patch.</p><p>This is a much more specific claim than “middle layers do reasoning.” It’s saying the reasoning cortex is organised into <strong>functional circuits</strong>: coherent multi-layer units that perform complete cognitive operations. Each circuit is an indivisible processing unit, and the $(i, j)$ sweeps seen in the heatmap is essentially discovering the boundaries of these circuits.</p><h3 id="mechanistic-interpretability-via-brain-damage">Mechanistic Interpretability via Brain Damage?</h3><p>This also reframes my informal experiments with <a href="https://github.com/oobabooga">oobabooga’s</a> <a href="https://github.com/oobabooga/text-generation-webui">Text Generation Web UI</a>. Throughout development, I’d been chatting with various re-layered configurations to see what they <em>felt like</em> in conversation.</p><p>The good ones were subtly but noticeably sharper. More coherent reasoning, better at holding long context, more natural conversational flow. The kind of difference where you can’t quite articulate what changed, but the model feels more <em>present</em>. Or maybe that’s just my imagination; vibe checks are hard to define.</p><p>The bad ones went properly unhinged. Some stuttered and fell into degenerate loops. Others developed bizarre personality disorders. One cheerfully announced <em>“Let’s act like cowboys! Yeehaw!”</em> apropos of nothing, and then descended into an unrecoverable giggling fit, generating pages of “hahaha” interspersed with cowboy references. ‘<em>Stoned</em>’ is best way I can describe it. I don’t know if LLM’s are ‘<em>partially conscious</em>’, or could be said to have some ‘<em>state of mind</em>’, but if so, this one was definitely enjoying itself.</p><p>These experiments suggest less “<em>slightly worse model</em>” and more “<em>genuine brain damage</em>.” Which makes sense under the circuit model — duplicating the wrong circuit is like enlarging a specific region of the brain at the expense of its neighbours. You don’t get a uniformly dumber person. You get someone with a specific neurological deficit. The cowboy model might have had its “social appropriateness” circuit disrupted by a doubled “creativity” circuit running unchecked. The stuttering models might have had their decoding circuits pushed out of alignment by extra reasoning depth they couldn’t translate back into coherent tokens.</p><p>If Transformer reasoning is organised into discrete circuits, it raises a series of fascinating questions. Are these circuits a necessary consequence of the architecture, and emerge from training at scale? Do different model families develop the <em>same</em> circuits in different layer positions, or do they develop fundamentally different architectures?</p><p>Luckily, I have already done a few; take a look and decide yourself:</p><hr /><h2 id="the-aftermath">The Aftermath</h2><p>My method is <em>orthogonal to fine-tuning</em>. Layer duplication changes the architecture; fine-tuning changes the weights. You can stack them. And people did to go on to score even higher in the Leaderboard:</p><p>MaziyarPanahi took RYS-XLarge and fine-tuned on top of it, producing <a href="https://huggingface.co/MaziyarPanahi/calme-2.4-rys-78b">calme-2.4-rys-78b</a>. Then <a href="https://huggingface.co/dfurman">dfurman</a> ran ORPO training on <em>that</em>, producing <a href="https://huggingface.co/dfurman/CalmeRys-78B-Orpo-v0.1">CalmeRys-78B-Orpo-v0.1</a>. MaziyarPanahi continued iterating with calme-3.1 and calme-3.2.</p><p>As of early 2026, the top four models on the Open LLM Leaderboard are:</p><ol><li>MaziyarPanahi/calme-3.2-instruct-78b — <strong>52.08</strong></li>
<li>MaziyarPanahi/calme-3.1-instruct-78b — <strong>51.29</strong></li>
<li>dfurman/CalmeRys-78B-Orpo-v0.1 — <strong>51.23</strong></li>
<li>MaziyarPanahi/calme-2.4-rys-78b — <strong>50.77</strong></li>
</ol><p>All 78B, and descendants of RYS-XLarge. All built on duplicated middle layers that were discovered using nothing but handful of hard math and emotional intelligence probes, on a pair of RTX 4090s, in my basement.</p><p>I never did the fine-tuning myself. It’s not that interesting to me. And I eventually lost interest in the leaderboard. It became increasingly clear that some submissions were training on the test set, and the whole thing was eventually shut down and rebooted. But I know the method is real, because I never used the leaderboard benchmarks for optimisation. The leaderboard was always just validation.</p><hr /><h2 id="looking-back-from-2026">Looking Back from 2026</h2><p>In 2024, the model merging community was obsessed with <em>weight interpolation</em>: SLERP, DARE-TIES, linear merges, pass-through layers. The idea was always to combine the learned parameters of different models into something greater than the sum of its parts. <a href="https://github.com/arcee-ai/mergekit">mergekit</a> was the tool of choice, and the leaderboard was flooded with creative combinations (<em>making me wait months to get my model benchmarked…</em>).</p><p>I was doing something different. I wasn’t changing what the model <em>knew</em>. I was changing how it <em>thought</em>. Layer duplication gives the model more iterations through its internal reasoning space without adding any new information. The difference between giving someone a bigger library and giving them more time to think. I was genuinely shocked when I took top spot on the leaderboard; but I think it’s proof that the method probably works.</p><p>The fact that this worked, and more specifically, that <em>only</em> circuit-sized blocks work, tells us how Transformers organise themselves during training. I now believe they develop a genuine functional anatomy. Early layers encode. Late layers decode. And in the middle, they build circuits: coherent, multi-layer processing units that perform complete cognitive operations. These circuits are indivisible. You can’t speed up a recipe by photocopying one step. But you can run the whole recipe twice.</p><p>Smaller models seem to be more complex. The encoding, reasoning, and decoding functions are more entangled, spread across the entire stack. I never found a single area of duplication that generalised across tasks, although clearly it was possible to boost one ‘<em>talent</em>’ at the expense of another. But as models get larger, the functional anatomy becomes more separated. The bigger models have more ‘<em>space</em>’ to develop generalised ‘thinking’ circuits, which may be why my method worked so dramatically on a 72B model. There’s a critical mass of parameters below which the ‘<em>reasoning cortex</em>’ hasn’t fully differentiated from the rest of the brain.</p><p>With the closure of the HuggingFace LLM leaderboard, and no access to powerful GPUs, I stopped running experiments. But with the flood of new Open Source models (<em>Qwen, MiniMax, GLM, and more</em>), and finally having just <a href="https://dnhkng.github.io/posts/hopper/">enough compute at home</a>, I have started working on the current batch of LLMs. The heatmaps keep coming back with the same general story, but every architecture has its own neuroanatomy. The brains are different. The principle is the same. And some models are looking really interesting (Qwen3.5 27B in particular). <strong><em>I will release the code along with uploading new RYS models and a blog post once my Hopper-system finishes grinding on MiniMax M2.5</em></strong>.</p><blockquote>
<p>Nvidia: Sponsor this project by sending me GB300 Grace Blackwell Ultra Desktop, as I NEED MOAR VRAM</p>
</blockquote><h3 id="one-more-thing">One More Thing</h3><p>Remember the architecture?</p><div class="language-plaintext highlighter-rouge"><div class="highlight"><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl">
<pre class="lineno">1
2
3
4
5
6
7
8
</pre></td>
<td class="rouge-code">
<pre>Example: (i, j) = (2, 7)
      0 → 1 → 2 → 3 → 4 → 5 → 6 ─┐
           ┌─────────────────────┘
           └→ 2 → 3 → 4 → 5 → 6 → 7 → 8
      duplicated: [2, 3, 4, 5, 6]
      path: [0, 1, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 7, 8]
</pre></td>
</tr></tbody></table></div></div><p>We have one horrible disjuncture, between layers 6 → 2. I have one more hypothesis: A little bit of fine-tuning on those two layers is all we really need. Fine-tuned RYS models dominate the Leaderboard. I suspect this junction is exactly what the fine-tuning fixes. And there’s a great reason to do this: <em>this method does not use extra VRAM!</em> For all these experiments, I duplicated layers via pointers; the layers are repeated without using more GPU memory. Of course, we do need more compute and more KV cache, but that’s a small price to pay for a verifiably better model. We can just ‘fix’ an actual copies of layers 2 and 6, <em>and repeat layers 3-4-5 as virtual copies</em>. If we fine-tune all layer, we turn virtual copies into real copies, and use up more VRAM.</p><hr /><p>Twenty years ago I was a PhD student dissecting rat brains. I never expected to end up performing brain surgery on artificial minds.</p><hr /><p><em>Special thanks to my wife, for putting up with months of evenings and weekends spent staring at heatmaps in the basement. And to the <a href="https://www.appliedai-institute.de/en/">appliedAI Institute</a> for the H100 compute that helped scale these experiments.</em></p></div>]]></description>
      <link>https://dnhkng.github.io/posts/rys/</link>
      <guid>https://dnhkng.github.io/posts/rys/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[microsoft/BitNet: Official inference framework for 1-bit LLMs]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">bitnet.cpp</h1><a id="user-content-bitnetcpp" class="anchor" aria-label="Permalink: bitnet.cpp" href="#bitnetcpp"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT" data-canonical-src="https://img.shields.io/badge/license-MIT-blue.svg" style="max-width: 100%;"></a>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/ac0e6350bd1a747fd6c3ffa64781612d3997df0c837a082a30d7af82a79ee225/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e302d626c7565"><img src="https://camo.githubusercontent.com/ac0e6350bd1a747fd6c3ffa64781612d3997df0c837a082a30d7af82a79ee225/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e302d626c7565" alt="version" data-canonical-src="https://img.shields.io/badge/version-1.0-blue" style="max-width: 100%;"></a></p>
<p dir="auto"><a href="https://huggingface.co/microsoft/BitNet-b1.58-2B-4T" rel="nofollow"><img src="./assets/header_model_release.png" alt="BitNet Model on Hugging Face" width="800" style="max-width: 100%;"></a></p>
<p dir="auto">Try it out via this <a href="https://demo-bitnet-h0h8hcfqeqhrf5gf.canadacentral-01.azurewebsites.net/" rel="nofollow">demo</a>, or build and run it on your own <a href="https://github.com/microsoft/BitNet?tab=readme-ov-file#build-from-source">CPU</a> or <a href="https://github.com/microsoft/BitNet/blob/main/gpu/README.md">GPU</a>.</p>
<p dir="auto">bitnet.cpp is the official inference framework for 1-bit LLMs (e.g., BitNet b1.58). It offers a suite of optimized kernels, that support <strong>fast</strong> and <strong>lossless</strong> inference of 1.58-bit models on CPU and GPU (NPU support will coming next).</p>
<p dir="auto">The first release of bitnet.cpp is to support inference on CPUs. bitnet.cpp achieves speedups of <strong>1.37x</strong> to <strong>5.07x</strong> on ARM CPUs, with larger models experiencing greater performance gains. Additionally, it reduces energy consumption by <strong>55.4%</strong> to <strong>70.0%</strong>, further boosting overall efficiency. On x86 CPUs, speedups range from <strong>2.37x</strong> to <strong>6.17x</strong> with energy reductions between <strong>71.9%</strong> to <strong>82.2%</strong>. Furthermore, bitnet.cpp can run a 100B BitNet b1.58 model on a single CPU, achieving speeds comparable to human reading (5-7 tokens per second), significantly enhancing the potential for running LLMs on local devices. Please refer to the <a href="https://arxiv.org/abs/2410.16144" rel="nofollow">technical report</a> for more details.</p>
<p dir="auto"><strong>Latest optimization</strong> introduces parallel kernel implementations with configurable tiling and embedding quantization support, achieving <strong>1.15x to 2.1x</strong> additional speedup over the original implementation across different hardware platforms and workloads. For detailed technical information, see the <a href="src/README.md">optimization guide</a>.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="./assets/performance.png"><img src="./assets/performance.png" alt="performance_comparison" width="800" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Demo</h2><a id="user-content-demo" class="anchor" aria-label="Permalink: Demo" href="#demo"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A demo of bitnet.cpp running a BitNet b1.58 3B model on Apple M2:</p>
<details open="" class="details-reset border rounded-2">
  <summary class="tmp-px-3 py-2">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-camera-video">
    <path d="M16 3.75v8.5a.75.75 0 0 1-1.136.643L11 10.575v.675A1.75 1.75 0 0 1 9.25 13h-7.5A1.75 1.75 0 0 1 0 11.25v-6.5C0 3.784.784 3 1.75 3h7.5c.966 0 1.75.784 1.75 1.75v.675l3.864-2.318A.75.75 0 0 1 16 3.75Zm-6.5 1a.25.25 0 0 0-.25-.25h-7.5a.25.25 0 0 0-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-6.5ZM11 8.825l3.5 2.1v-5.85l-3.5 2.1Z"></path>
</svg>
    <span class="m-1">demo.mp4</span>
    <span class="dropdown-caret"></span>
  </summary>

  <video src="https://private-user-images.githubusercontent.com/54800242/377447164-7f46b736-edec-4828-b809-4be780a3e5b1.mp4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMyOTY1OTUsIm5iZiI6MTc3MzI5NjI5NSwicGF0aCI6Ii81NDgwMDI0Mi8zNzc0NDcxNjQtN2Y0NmI3MzYtZWRlYy00ODI4LWI4MDktNGJlNzgwYTNlNWIxLm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEyVDA2MTgxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNlNjUwNjk2ZjE5NjA5ZmQ1ODc0Y2U1NWQzMDIyNTBiOTM1ZGIwZDc5NWU2NDE2NDQ5YjJmNDliZDJiMGMxMjQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.ZuoYDLCNknRi0dh2SB48ZsDCrhZjXEzNl7Dbw_ocu10" data-canonical-src="https://private-user-images.githubusercontent.com/54800242/377447164-7f46b736-edec-4828-b809-4be780a3e5b1.mp4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMyOTY1OTUsIm5iZiI6MTc3MzI5NjI5NSwicGF0aCI6Ii81NDgwMDI0Mi8zNzc0NDcxNjQtN2Y0NmI3MzYtZWRlYy00ODI4LWI4MDktNGJlNzgwYTNlNWIxLm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTIlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEyVDA2MTgxNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWNlNjUwNjk2ZjE5NjA5ZmQ1ODc0Y2U1NWQzMDIyNTBiOTM1ZGIwZDc5NWU2NDE2NDQ5YjJmNDliZDJiMGMxMjQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.ZuoYDLCNknRi0dh2SB48ZsDCrhZjXEzNl7Dbw_ocu10" controls="controls" muted="muted" class="d-block rounded-bottom-2 border-top width-fit" style="max-height:640px; min-height: 200px">

  </video>
</details>

<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">What's New:</h2><a id="user-content-whats-new" class="anchor" aria-label="Permalink: What's New:" href="#whats-new"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>01/15/2026 <a href="https://github.com/microsoft/BitNet/blob/main/src/README.md">BitNet CPU Inference Optimization</a> <a target="_blank" rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/78f781c13c1240ba64b2be628840d5f7da48faa1ca3ea8a6648e01238e07e0b2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e45572d726564"><img src="https://camo.githubusercontent.com/78f781c13c1240ba64b2be628840d5f7da48faa1ca3ea8a6648e01238e07e0b2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e45572d726564" alt="NEW" data-canonical-src="https://img.shields.io/badge/NEW-red" style="max-width: 100%;"></a></li>
<li>05/20/2025 <a href="https://github.com/microsoft/BitNet/blob/main/gpu/README.md">BitNet Official GPU inference kernel</a></li>
<li>04/14/2025 <a href="https://huggingface.co/microsoft/BitNet-b1.58-2B-4T" rel="nofollow">BitNet Official 2B Parameter Model on Hugging Face</a></li>
<li>02/18/2025 <a href="https://arxiv.org/abs/2502.11880" rel="nofollow">Bitnet.cpp: Efficient Edge Inference for Ternary LLMs</a></li>
<li>11/08/2024 <a href="https://arxiv.org/abs/2411.04965" rel="nofollow">BitNet a4.8: 4-bit Activations for 1-bit LLMs</a></li>
<li>10/21/2024 <a href="https://arxiv.org/abs/2410.16144" rel="nofollow">1-bit AI Infra: Part 1.1, Fast and Lossless BitNet b1.58 Inference on CPUs</a></li>
<li>10/17/2024 bitnet.cpp 1.0 released.</li>
<li>03/21/2024 <a href="https://github.com/microsoft/unilm/blob/master/bitnet/The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ.pdf">The-Era-of-1-bit-LLMs__Training_Tips_Code_FAQ</a></li>
<li>02/27/2024 <a href="https://arxiv.org/abs/2402.17764" rel="nofollow">The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bits</a></li>
<li>10/17/2023 <a href="https://arxiv.org/abs/2310.11453" rel="nofollow">BitNet: Scaling 1-bit Transformers for Large Language Models</a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Acknowledgements</h2><a id="user-content-acknowledgements" class="anchor" aria-label="Permalink: Acknowledgements" href="#acknowledgements"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This project is based on the <a href="https://github.com/ggerganov/llama.cpp">llama.cpp</a> framework. We would like to thank all the authors for their contributions to the open-source community. Also, bitnet.cpp's kernels are built on top of the Lookup Table methodologies pioneered in <a href="https://github.com/microsoft/T-MAC/">T-MAC</a>. For inference of general low-bit LLMs beyond ternary models, we recommend using T-MAC.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Official Models</h2><a id="user-content-official-models" class="anchor" aria-label="Permalink: Official Models" href="#official-models"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
    
    <tbody><tr>
        <th rowspan="2">Model</th>
        <th rowspan="2">Parameters</th>
        <th rowspan="2">CPU</th>
        <th colspan="3">Kernel</th>
    </tr>
    <tr>
        <th>I2_S</th>
        <th>TL1</th>
        <th>TL2</th>
    </tr>
    <tr>
        <td rowspan="2"><a href="https://huggingface.co/microsoft/BitNet-b1.58-2B-4T" rel="nofollow">BitNet-b1.58-2B-4T</a></td>
        <td rowspan="2">2.4B</td>
        <td>x86</td>
        <td>✅</td>
        <td>❌</td>
        <td>✅</td>
    </tr>
    <tr>
        <td>ARM</td>
        <td>✅</td>
        <td>✅</td>
        <td>❌</td>
    </tr>
</tbody></table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Supported Models</h2><a id="user-content-supported-models" class="anchor" aria-label="Permalink: Supported Models" href="#supported-models"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">❗️<strong>We use existing 1-bit LLMs available on <a href="https://huggingface.co/" rel="nofollow">Hugging Face</a> to demonstrate the inference capabilities of bitnet.cpp. We hope the release of bitnet.cpp will inspire the development of 1-bit LLMs in large-scale settings in terms of model size and training tokens.</strong></p>
<markdown-accessiblity-table><table>
    
    <tbody><tr>
        <th rowspan="2">Model</th>
        <th rowspan="2">Parameters</th>
        <th rowspan="2">CPU</th>
        <th colspan="3">Kernel</th>
    </tr>
    <tr>
        <th>I2_S</th>
        <th>TL1</th>
        <th>TL2</th>
    </tr>
    <tr>
        <td rowspan="2"><a href="https://huggingface.co/1bitLLM/bitnet_b1_58-large" rel="nofollow">bitnet_b1_58-large</a></td>
        <td rowspan="2">0.7B</td>
        <td>x86</td>
        <td>✅</td>
        <td>❌</td>
        <td>✅</td>
    </tr>
    <tr>
        <td>ARM</td>
        <td>✅</td>
        <td>✅</td>
        <td>❌</td>
    </tr>
    <tr>
        <td rowspan="2"><a href="https://huggingface.co/1bitLLM/bitnet_b1_58-3B" rel="nofollow">bitnet_b1_58-3B</a></td>
        <td rowspan="2">3.3B</td>
        <td>x86</td>
        <td>❌</td>
        <td>❌</td>
        <td>✅</td>
    </tr>
    <tr>
        <td>ARM</td>
        <td>❌</td>
        <td>✅</td>
        <td>❌</td>
    </tr>
    <tr>
        <td rowspan="2"><a href="https://huggingface.co/HF1BitLLM/Llama3-8B-1.58-100B-tokens" rel="nofollow">Llama3-8B-1.58-100B-tokens</a></td>
        <td rowspan="2">8.0B</td>
        <td>x86</td>
        <td>✅</td>
        <td>❌</td>
        <td>✅</td>
    </tr>
    <tr>
        <td>ARM</td>
        <td>✅</td>
        <td>✅</td>
        <td>❌</td>
    </tr>
    <tr>
        <td rowspan="2"><a href="https://huggingface.co/collections/tiiuae/falcon3-67605ae03578be86e4e87026" rel="nofollow">Falcon3 Family</a></td>
        <td rowspan="2">1B-10B</td>
        <td>x86</td>
        <td>✅</td>
        <td>❌</td>
        <td>✅</td>
    </tr>
    <tr>
        <td>ARM</td>
        <td>✅</td>
        <td>✅</td>
        <td>❌</td>
    </tr>
    <tr>
        <td rowspan="2"><a href="https://huggingface.co/collections/tiiuae/falcon-edge-series-6804fd13344d6d8a8fa71130" rel="nofollow">Falcon-E Family</a></td>
        <td rowspan="2">1B-3B</td>
        <td>x86</td>
        <td>✅</td>
        <td>❌</td>
        <td>✅</td>
    </tr>
    <tr>
        <td>ARM</td>
        <td>✅</td>
        <td>✅</td>
        <td>❌</td>
    </tr>
</tbody></table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Installation</h2><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Requirements</h3><a id="user-content-requirements" class="anchor" aria-label="Permalink: Requirements" href="#requirements"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>python&gt;=3.9</li>
<li>cmake&gt;=3.22</li>
<li>clang&gt;=18
<ul dir="auto">
<li>
<p dir="auto">For Windows users, install <a href="https://visualstudio.microsoft.com/downloads/" rel="nofollow">Visual Studio 2022</a>. In the installer, toggle on at least the following options(this also automatically installs the required additional tools like CMake):</p>
<ul dir="auto">
<li>Desktop-development with C++</li>
<li>C++-CMake Tools for Windows</li>
<li>Git for Windows</li>
<li>C++-Clang Compiler for Windows</li>
<li>MS-Build Support for LLVM-Toolset (clang)</li>
</ul>
</li>
<li>
<p dir="auto">For Debian/Ubuntu users, you can download with <a href="https://apt.llvm.org/" rel="nofollow">Automatic installation script</a></p>
<p dir="auto"><code>bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"</code></p>
</li>
</ul>
</li>
<li>conda (highly recommend)</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Build from source</h3><a id="user-content-build-from-source" class="anchor" aria-label="Permalink: Build from source" href="#build-from-source"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-alert markdown-alert-important" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-report mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>Important</p><p dir="auto">If you are using Windows, please remember to always use a Developer Command Prompt / PowerShell for VS2022 for the following commands. Please refer to the FAQs below if you see any issues.</p>
</div>
<ol dir="auto">
<li>Clone the repo</li>
</ol>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone --recursive https://github.com/microsoft/BitNet.git
cd BitNet"><pre>git clone --recursive https://github.com/microsoft/BitNet.git
<span class="pl-c1">cd</span> BitNet</pre></div>
<ol start="2" dir="auto">
<li>Install the dependencies</li>
</ol>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# (Recommended) Create a new conda environment
conda create -n bitnet-cpp python=3.9
conda activate bitnet-cpp

pip install -r requirements.txt"><pre><span class="pl-c"><span class="pl-c">#</span> (Recommended) Create a new conda environment</span>
conda create -n bitnet-cpp python=3.9
conda activate bitnet-cpp

pip install -r requirements.txt</pre></div>
<ol start="3" dir="auto">
<li>Build the project</li>
</ol>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Manually download the model and run with local path
huggingface-cli download microsoft/BitNet-b1.58-2B-4T-gguf --local-dir models/BitNet-b1.58-2B-4T
python setup_env.py -md models/BitNet-b1.58-2B-4T -q i2_s
"><pre><span class="pl-c"><span class="pl-c">#</span> Manually download the model and run with local path</span>
huggingface-cli download microsoft/BitNet-b1.58-2B-4T-gguf --local-dir models/BitNet-b1.58-2B-4T
python setup_env.py -md models/BitNet-b1.58-2B-4T -q i2_s
</pre></div>
<pre>usage: setup_env.py [-h] [--hf-repo {1bitLLM/bitnet_b1_58-large,1bitLLM/bitnet_b1_58-3B,HF1BitLLM/Llama3-8B-1.58-100B-tokens,tiiuae/Falcon3-1B-Instruct-1.58bit,tiiuae/Falcon3-3B-Instruct-1.58bit,tiiuae/Falcon3-7B-Instruct-1.58bit,tiiuae/Falcon3-10B-Instruct-1.58bit}] [--model-dir MODEL_DIR] [--log-dir LOG_DIR] [--quant-type {i2_s,tl1}] [--quant-embd]
                    [--use-pretuned]

Setup the environment for running inference

optional arguments:
  -h, --help            show this help message and exit
  --hf-repo {1bitLLM/bitnet_b1_58-large,1bitLLM/bitnet_b1_58-3B,HF1BitLLM/Llama3-8B-1.58-100B-tokens,tiiuae/Falcon3-1B-Instruct-1.58bit,tiiuae/Falcon3-3B-Instruct-1.58bit,tiiuae/Falcon3-7B-Instruct-1.58bit,tiiuae/Falcon3-10B-Instruct-1.58bit}, -hr {1bitLLM/bitnet_b1_58-large,1bitLLM/bitnet_b1_58-3B,HF1BitLLM/Llama3-8B-1.58-100B-tokens,tiiuae/Falcon3-1B-Instruct-1.58bit,tiiuae/Falcon3-3B-Instruct-1.58bit,tiiuae/Falcon3-7B-Instruct-1.58bit,tiiuae/Falcon3-10B-Instruct-1.58bit}
                        Model used for inference
  --model-dir MODEL_DIR, -md MODEL_DIR
                        Directory to save/load the model
  --log-dir LOG_DIR, -ld LOG_DIR
                        Directory to save the logging info
  --quant-type {i2_s,tl1}, -q {i2_s,tl1}
                        Quantization type
  --quant-embd          Quantize the embeddings to f16
  --use-pretuned, -p    Use the pretuned kernel parameters
</pre>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Usage</h2><a id="user-content-usage" class="anchor" aria-label="Permalink: Usage" href="#usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Basic usage</h3><a id="user-content-basic-usage" class="anchor" aria-label="Permalink: Basic usage" href="#basic-usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Run inference with the quantized model
python run_inference.py -m models/BitNet-b1.58-2B-4T/ggml-model-i2_s.gguf -p &quot;You are a helpful assistant&quot; -cnv"><pre><span class="pl-c"><span class="pl-c">#</span> Run inference with the quantized model</span>
python run_inference.py -m models/BitNet-b1.58-2B-4T/ggml-model-i2_s.gguf -p <span class="pl-s"><span class="pl-pds">"</span>You are a helpful assistant<span class="pl-pds">"</span></span> -cnv</pre></div>
<pre>usage: run_inference.py [-h] [-m MODEL] [-n N_PREDICT] -p PROMPT [-t THREADS] [-c CTX_SIZE] [-temp TEMPERATURE] [-cnv]

Run inference

optional arguments:
  -h, --help            show this help message and exit
  -m MODEL, --model MODEL
                        Path to model file
  -n N_PREDICT, --n-predict N_PREDICT
                        Number of tokens to predict when generating text
  -p PROMPT, --prompt PROMPT
                        Prompt to generate text from
  -t THREADS, --threads THREADS
                        Number of threads to use
  -c CTX_SIZE, --ctx-size CTX_SIZE
                        Size of the prompt context
  -temp TEMPERATURE, --temperature TEMPERATURE
                        Temperature, a hyperparameter that controls the randomness of the generated text
  -cnv, --conversation  Whether to enable chat mode or not (for instruct models.)
                        (When this option is turned on, the prompt specified by -p will be used as the system prompt.)
</pre>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Benchmark</h3><a id="user-content-benchmark" class="anchor" aria-label="Permalink: Benchmark" href="#benchmark"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">We provide scripts to run the inference benchmark providing a model.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="usage: e2e_benchmark.py -m MODEL [-n N_TOKEN] [-p N_PROMPT] [-t THREADS]  
   
Setup the environment for running the inference  
   
required arguments:  
  -m MODEL, --model MODEL  
                        Path to the model file. 
   
optional arguments:  
  -h, --help  
                        Show this help message and exit. 
  -n N_TOKEN, --n-token N_TOKEN  
                        Number of generated tokens. 
  -p N_PROMPT, --n-prompt N_PROMPT  
                        Prompt to generate text from. 
  -t THREADS, --threads THREADS  
                        Number of threads to use. "><pre class="notranslate"><code>usage: e2e_benchmark.py -m MODEL [-n N_TOKEN] [-p N_PROMPT] [-t THREADS]  
   
Setup the environment for running the inference  
   
required arguments:  
  -m MODEL, --model MODEL  
                        Path to the model file. 
   
optional arguments:  
  -h, --help  
                        Show this help message and exit. 
  -n N_TOKEN, --n-token N_TOKEN  
                        Number of generated tokens. 
  -p N_PROMPT, --n-prompt N_PROMPT  
                        Prompt to generate text from. 
  -t THREADS, --threads THREADS  
                        Number of threads to use. 
</code></pre></div>
<p dir="auto">Here's a brief explanation of each argument:</p>
<ul dir="auto">
<li><code>-m</code>, <code>--model</code>: The path to the model file. This is a required argument that must be provided when running the script.</li>
<li><code>-n</code>, <code>--n-token</code>: The number of tokens to generate during the inference. It is an optional argument with a default value of 128.</li>
<li><code>-p</code>, <code>--n-prompt</code>: The number of prompt tokens to use for generating text. This is an optional argument with a default value of 512.</li>
<li><code>-t</code>, <code>--threads</code>: The number of threads to use for running the inference. It is an optional argument with a default value of 2.</li>
<li><code>-h</code>, <code>--help</code>: Show the help message and exit. Use this argument to display usage information.</li>
</ul>
<p dir="auto">For example:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="python utils/e2e_benchmark.py -m /path/to/model -n 200 -p 256 -t 4  "><pre>python utils/e2e_benchmark.py -m /path/to/model -n 200 -p 256 -t 4  </pre></div>
<p dir="auto">This command would run the inference benchmark using the model located at <code>/path/to/model</code>, generating 200 tokens from a 256 token prompt, utilizing 4 threads.</p>
<p dir="auto">For the model layout that do not supported by any public model, we provide scripts to generate a dummy model with the given model layout, and run the benchmark on your machine:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="python utils/generate-dummy-bitnet-model.py models/bitnet_b1_58-large --outfile models/dummy-bitnet-125m.tl1.gguf --outtype tl1 --model-size 125M

# Run benchmark with the generated model, use -m to specify the model path, -p to specify the prompt processed, -n to specify the number of token to generate
python utils/e2e_benchmark.py -m models/dummy-bitnet-125m.tl1.gguf -p 512 -n 128"><pre>python utils/generate-dummy-bitnet-model.py models/bitnet_b1_58-large --outfile models/dummy-bitnet-125m.tl1.gguf --outtype tl1 --model-size 125M

<span class="pl-c"><span class="pl-c">#</span> Run benchmark with the generated model, use -m to specify the model path, -p to specify the prompt processed, -n to specify the number of token to generate</span>
python utils/e2e_benchmark.py -m models/dummy-bitnet-125m.tl1.gguf -p 512 -n 128</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Convert from <code>.safetensors</code> Checkpoints</h3><a id="user-content-convert-from-safetensors-checkpoints" class="anchor" aria-label="Permalink: Convert from .safetensors Checkpoints" href="#convert-from-safetensors-checkpoints"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Prepare the .safetensors model file
huggingface-cli download microsoft/bitnet-b1.58-2B-4T-bf16 --local-dir ./models/bitnet-b1.58-2B-4T-bf16

# Convert to gguf model
python ./utils/convert-helper-bitnet.py ./models/bitnet-b1.58-2B-4T-bf16"><pre><span class="pl-c"><span class="pl-c">#</span> Prepare the .safetensors model file</span>
huggingface-cli download microsoft/bitnet-b1.58-2B-4T-bf16 --local-dir ./models/bitnet-b1.58-2B-4T-bf16

<span class="pl-c"><span class="pl-c">#</span> Convert to gguf model</span>
python ./utils/convert-helper-bitnet.py ./models/bitnet-b1.58-2B-4T-bf16</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">FAQ (Frequently Asked Questions)📌</h3><a id="user-content-faq-frequently-asked-questions" class="anchor" aria-label="Permalink: FAQ (Frequently Asked Questions)📌" href="#faq-frequently-asked-questions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Q1: The build dies with errors building llama.cpp due to issues with std::chrono in log.cpp?</h4><a id="user-content-q1-the-build-dies-with-errors-building-llamacpp-due-to-issues-with-stdchrono-in-logcpp" class="anchor" aria-label="Permalink: Q1: The build dies with errors building llama.cpp due to issues with std::chrono in log.cpp?" href="#q1-the-build-dies-with-errors-building-llamacpp-due-to-issues-with-stdchrono-in-logcpp"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>A:</strong>
This is an issue introduced in recent version of llama.cpp. Please refer to this <a href="https://github.com/tinglou/llama.cpp/commit/4e3db1e3d78cc1bcd22bcb3af54bd2a4628dd323">commit</a> in the <a href="https://github.com/abetlen/llama-cpp-python/issues/1942" data-hovercard-type="issue" data-hovercard-url="/abetlen/llama-cpp-python/issues/1942/hovercard">discussion</a> to fix this issue.</p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Q2: How to build with clang in conda environment on windows?</h4><a id="user-content-q2-how-to-build-with-clang-in-conda-environment-on-windows" class="anchor" aria-label="Permalink: Q2: How to build with clang in conda environment on windows?" href="#q2-how-to-build-with-clang-in-conda-environment-on-windows"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>A:</strong>
Before building the project, verify your clang installation and access to Visual Studio tools by running:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="clang -v"><pre class="notranslate"><code>clang -v
</code></pre></div>
<p dir="auto">This command checks that you are using the correct version of clang and that the Visual Studio tools are available. If you see an error message such as:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="'clang' is not recognized as an internal or external command, operable program or batch file."><pre class="notranslate"><code>'clang' is not recognized as an internal or external command, operable program or batch file.
</code></pre></div>
<p dir="auto">It indicates that your command line window is not properly initialized for Visual Studio tools.</p>
<p dir="auto">• If you are using Command Prompt, run:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&quot;C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat&quot; -startdir=none -arch=x64 -host_arch=x64"><pre class="notranslate"><code>"C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat" -startdir=none -arch=x64 -host_arch=x64
</code></pre></div>
<p dir="auto">• If you are using Windows PowerShell, run the following commands:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Import-Module &quot;C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\Microsoft.VisualStudio.DevShell.dll&quot; Enter-VsDevShell 3f0e31ad -SkipAutomaticLocation -DevCmdArguments &quot;-arch=x64 -host_arch=x64&quot;"><pre class="notranslate"><code>Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" Enter-VsDevShell 3f0e31ad -SkipAutomaticLocation -DevCmdArguments "-arch=x64 -host_arch=x64"
</code></pre></div>
<p dir="auto">These steps will initialize your environment and allow you to use the correct Visual Studio tools.</p>
</article></div>]]></description>
      <link>https://github.com/microsoft/BitNet</link>
      <guid>https://github.com/microsoft/BitNet</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Zen fascists will control you...]]></title>
      <description><![CDATA[<p>In 1979, a punk band from San Francisco recorded a song about the Governor of California. It was a joke, mostly. Jerry Brown was a Democrat, a Buddhist, a man who dated Linda Ronstadt and discussed limits and simplicity at a moment when America was in no mood for either.</p><p>The Dead Kennedys called him a "Zen fascist" and suggested, with cheerful malice, that he would one day run concentration camps fuelled by organic food. I’m not sure that anyway, even the band, took it entirely seriously.</p><p>They should have.</p><hr /><p>The word that the song never uses, but engages with constantly is <em>purity</em>. Jello Biafra wasn't writing a political science paper but structurally, “purity” runs all the way through it. The Zen fascist doesn't want to punish you out of hatred. He wants to cleanse you for your own good. He has <em>done the work</em>. He has achieved a higher state. And he would very much like you to achieve it too, whether you want to or not.</p><p>This is the thing about the politics of purity<a><sup>[1]</sup></a> that makes it so durable, and so dangerous: it doesn't require malice. It requires only the conviction that you know what clean looks like, and the will to impose it on others, for their own good.</p><p>Both the counterculture and the authoritarian right are obsessed with purity. The targets differ wildly — the body, the race, the culture, the blood, the food, the mind. But the cognitive shape is identical. And that shared shape is the on-ramp. It's how you can get from granola to fascism without ever feeling like you've made a wrong turn.</p><hr /><p>It’s August 1969. Half a million people are in a field in upstate New York, and Joni Mitchell is not among them. She watched Woodstock on a hotel television in New York City, having been advised by her manager not to go — there were television commitments, logistics, the usual stuff of a successful music career.</p><p>She wrote a song about Woodstock anyway. And it contains, in two lines, much of the ideology of the counterculture at its most hopeful and most revealing.</p><p><em>We are stardust, we are golden.</em> This is the counterculture's central claim about human nature, compressed into eight words. We are not merely human — we are cosmic, made of the stuff that stars are made of. It's the Human Potential Movement set to music. Nobody listening to the song, then or now, hears it as elitist. It definitely wasn't <em>intended</em> as elitist. Mitchell was expressing something she genuinely felt, something that was, in its way, beautiful: a refusal of the diminishment that ordinary life, and the expectations of 1960s parents, impose.</p><p>But strip it down and look at the structure. <em>We are golden</em> is, first of all, a note about the rarity of humanity. Gold is rare because it's made in the hearts of stars. Humanity is rare, too.</p><p>But it's impossible to use "gold" as a metaphor without acknowledging that it is also a claim about elevated status. It contains a hierarchy. The person who knows they are made of stardust has access to a truth that others are missing. They have, in some meaningful sense, <em>woken up</em> to their own cosmic significance.</p><p>And if some people have woken up to this and others remain asleep — well, that's a ladder. Somebody is at the top of it, and some people are at the bottom.</p><p>Then the second line. <em>And we've got to get ourselves back to the garden.</em> The garden is Eden, of course. And Eden is not just nature. It is the prelapsarian state, the condition of original purity before contamination entered the world<a><sup>[2]</sup></a>. The Biblical Fall was a corruption. The desire to return to the garden is a desire to be clean again, to recover what was lost, to expel whatever (or whoever) defiled us.</p><p>This is, structurally, identical to blood and soil romanticism: there was a pure original state, we have been corrupted, we must return. The sandals and the jackboots are walking along the same path. The reasons for traveling that road might differ. The longing is the same.</p><p>None of this is Joni Mitchell's fault. She was not a fascist. She was not even close to a fascist. She was a profoundly humane artist, writing from genuine feeling at a genuine moment. But the point is not what she intended. The point is that the cultural water of the time was so thoroughly saturated with purity logic — so completely marinated in the idea that humanity had a golden original state from which it had fallen and to which it must return — that it was present in the most beautiful songs, sung by the most gifted people, at the most hopeful moment anyone could remember. And nobody seemed to notice. Nobody thought, “this is a purity myth”. And that meant no one really asked the obvious question: “pure, compared to what? Contaminated by what - or whom?”</p><p>Purity logic doesn't barge in. It usually arrives as poetry.</p><hr /><p>To understand how we got here from there, you have to go back to a place that appears, on the surface, to have nothing to do with politics at all.</p><p>Esalen. Big Sur. 1962.</p><p>A former Stanford wrestling champion named Dick Price and a former Stanford psychology student named Michael Murphy opened a retreat centre on the California coast. The premise was simple and, at the time, genuinely radical: human beings were capable of far more than ordinary life allowed. Psychology, spirituality, bodywork, psychedelics — all of these were tools for expansion. The potential was there, waiting. Most people just hadn't accessed it yet.</p><p>This was the Human Potential Movement, and it would produce some of the most ambitious and some of the most dangerous ideas of the late twentieth century, ones which are still haunting us today.</p><p>The ambition is easy to understand. The sixties were intoxicating — new therapies, new drugs, new ways of thinking about consciousness and the self. If ordinary human life was an artificial constraint, then removing the constraint was liberation. That felt good. It felt progressive. It felt a lot better than dying in a pointless war Vietnam.</p><p>What nobody wanted to examine too carefully was the hierarchy buried in the logic. If some people had unlocked their potential and others hadn't, that was, structurally speaking, a claim about superior and inferior human beings. The language was therapeutic. The underlying architecture was hierarchical.</p><p>The Human Potential Movement didn't create a new type of person. It created a new vocabulary for an ancient idea: that some people are simply more evolved than others, and that their higher development confers upon them special authority. The crystals and the encounter groups were the wrapping. Inside was something older and more troubling.</p><hr /><p>Stewart Brand noticed something in 1968. He put it on the cover of the <em>Whole Earth Catalog</em>, a question he'd been trying to get NASA to answer for years: <em>Why haven't we seen a photograph of the whole Earth yet?</em></p><p>When the photo came — <em>Earthrise</em>, from Apollo 8 — it was a symbol of change. Here was the planet, fragile and whole and borderless. It became the emblem of a new kind of environmental consciousness, of global thinking, of the idea that humanity was a single tribe on a single fragile lifeboat. Brand put it on the cover of his catalogue and built a small media empire around the idea that individuals, armed with the right tools and the right information, could remake the world from the bottom up.</p><p>The <em>Whole Earth Catalog</em> was a genuinely strange object. Part hippie bible, part mail-order directory for geodesic dome components, it celebrated self-sufficiency, technology, and the idea that the right tools in the right hands could replace the need for institutions entirely. You didn't need the government. You didn't need corporations. You needed knowledge and will and the right equipment.</p><p>Fred Turner, in his 2006 book <em>From Counterculture to Cyberculture</em>, traced what happened next. The people who grew up with the <em>Whole Earth Catalog</em> went to Silicon Valley. They took the anti-institutionalism, the utopianism, the faith in individual transformation, and they applied it to computers. The personal computer wasn't just a machine. It was an instrument of consciousness expansion. The computer was the acid trip made silicon.</p><p>In 1995, two British academics named Richard Barbrook and Andy Cameron looked at what Silicon Valley had become and named what they saw: the Californian Ideology. A bizarre but remarkably stable hybrid, countercultural bohemianism fused with aggressive free-market libertarianism. The commune and the stock option. Jefferson Airplane and Ayn Rand. And it seemed to work.</p><p>The contradiction at its heart was never resolved because resolving it was never the point. The point was the story it told about itself: that technology was liberation, that the market was freedom, that the people building this stuff were, in some meaningful sense, <em>better</em> — more creative, more visionary, more <em>evolved</em> — than the suits who'd run everything before. They were doing the Human Potential Movement's work with microchips instead of encounter groups.</p><hr /><p>In 1979, the same year the Dead Kennedys were warning San Francisco about Jerry Brown, a man named Werner Erhard was running something called est — Erhard Seminars Training<a><sup>[3]</sup></a>. You would pay to spend a weekend being berated by a trainer in a hotel conference room. You could not leave. You could not use the toilet without permission. By the end, if it worked, you would have broken through your own mental limitations and achieved a new relationship with <em>responsibility</em> — which, in est's vocabulary, meant accepting that everything that happened to you was, on some level, your own creation.</p><p>est was not fringe. It was fashionable. Celebrities did it. Business executives did it. It fed directly into the self-help industrial complex that would dominate the next four decades and make a lot of people pretty rich. Every single influencers you see selling a course around turning you into <em>better</em> you is, knowingly or unknowingly, following a path created by est.</p><p>It also made something explicit that the Human Potential Movement had kept implicit: that your suffering was your fault, that your failure was your fault, and that transcending both was a matter of will and clarity<a><sup>[4]</sup></a>. This was purity logic applied to the psyche. The contaminated mind — limited, victimised, stuck in old patterns — could be cleaned. The clean mind was free.</p><p>You can draw a straight line from est to the productivity cult of contemporary tech culture, to the biohacking movement, to the particular flavour of self-optimisation that has become the dominant religion of the Silicon Valley overclass. Bryan Johnson, the tech entrepreneur who spends millions of dollars a year attempting to reverse his biological age, submitting his body to a programme of measurement and intervention so comprehensive it makes Victorian-era medical quackery look modest, is doing est with better lab equipment. He has decided his body is a problem to be solved. Contamination — entropy, age, ordinary human physicality — is to be defeated by will and resources.</p><p>Peter Thiel's investments in parabiosis — the transfusion of blood from younger bodies, in pursuit of the vitality it supposedly contains — has the quality of alchemy. Or, if you're feeling less charitable, something older and darker. This is a billionaire trying to absorb life from the young because he has decided that ordinary mortality is an affront. The purity obsession has become vampiric.</p><p>This image of the powerful feeding on youth to purchase their own escape from mortality is not new. In 1969 — the same year Joni Mitchell watched Woodstock on a hotel television — the science fiction writer Norman Spinrad published <em>Bug Jack Barron</em>, a novel whose central villain, Benedict Howard, runs a foundation dedicated to achieving human immortality. What he doesn't tell anyone is that the process works. It also requires children. The eternal life of the wealthy is purchased, directly and without metaphor, from the bodies of the young.</p><p>The novel was serialised in Michael Moorcock's <em>New Worlds</em> magazine and promptly condemned in Parliament, refused by WH Smith, and declared obscene. What the British establishment was reacting to, beneath the surface scandal, was probably the image itself — the transaction it made visible, the thing it refused to dress up. Spinrad was writing fiction. He was also writing a critique. Faced with the same choices as Benedict Howard, Thiel continues writing cheques.</p><hr /><p>There is a philosopher who sits at the centre of all of this, largely unacknowledged, and his name is Friedrich Nietzsche.</p><p>The Dead Kennedys knew this, even if they didn't say it directly. <em>California Über Alles</em> — the title tells you everything. <em>Über</em> isn't just a German intensifier. It points at Nietzsche's <em>Übermensch</em>, the Superman, the figure who has transcended ordinary human limitation. The word sits in the middle of the title of the song like a splinter.</p><p>But Joni Mitchell heard it too, in her own way, on that hotel television in 1969. <em>We are stardust.</em> We are, each of us, our own <em>Übermensch.</em> Inside you is your our own golden being, waiting to transcend. The counterculture democratised the Superman. Everyone could be golden.</p><p>Which sounds like the opposite of fascism, until you realise that a world of seven billion self-identified golden beings still requires someone to decide who has done enough work to have truly earned the designation.</p><p>The <em>Übermensch</em> runs like a piece of coaxial cable strung from Esalen through Silicon Valley to the present moment. Nietzsche himself would have been appalled by many of its manifestations — he despised nationalism and antisemitism — but his concepts proved incredibly portable. The idea of the higher man, the man beyond conventional morality, the man whose exceptional nature exempts him from ordinary rules: this is the founding myth of every cult of elite consciousness, in every decade, in every age. And very especially now.</p><p>Curtis Yarvin — a software engineer who blogs under the name Mencius Moldbug and who functions, with remarkable openness, as Peter Thiel's house philosopher — makes the connection explicit in a way that most tech figures are canny enough to avoid. His neoreactionary politics rest on a single claim: that democracy is a system designed to empower the mediocre at the expense of the genuinely capable. The solution is to hand power to a cognitive and managerial elite — a CEO of everything, essentially — and stop pretending that all human judgement is equally valid.</p><p>This is the Human Potential Movement with the therapeutic vocabulary stripped away. The hierarchy of consciousness that Esalen spoke of in the language of growth and healing, Yarvin speaks of in the language of management (and political) efficiency. The underlying content is identical. Some people are more evolved. They should be in charge. The rest of us should be grateful to be guided by the <em>golden</em>.</p><p>The "red pill" metaphor that saturates contemporary online right culture is the same structure again, rendered in the vocabulary of a 1999 science fiction film<a><sup>[5]</sup></a>. You were asleep. Now you're awake. You were contaminated by mainstream thinking, liberal institutions, fake news, the Cathedral — Yarvin's term for the combination of academia, media, and government that he believes manufactures consent. Now you're clean. You can see.</p><p>This is a purification ritual. The content — the specific beliefs you acquire when you "wake up" — matters less than the structure. You have been initiated. You have separated yourself from the unclean. You belong now to the community of the knowing.</p><p>It is, structurally, identical to the yoga retreat, the est weekend, the Esalen workshop. You arrive limited and leave transformed. The guru differs. The logic doesn't.</p><hr /><p>Little of this happened accidentally. The far right actively recruits from wellness communities, from conspiracy spaces, from the ragged edges of countercultural scepticism because it understands the structural affinities better than most of the people being recruited do.</p><p>The wellness-to-conspiracy pipeline that became visible during COVID — the yoga teachers sharing QAnon memes, the organic food enthusiasts finding themselves on Telegram channels with people whose other interests they would, under other circumstances, find alarming — wasn't spontaneous radicalisation. It was targeted. The pipeline was built, deliberately, by people who understood that a person who already distrusts pharmaceutical companies, already believes in hidden knowledge, already thinks they've seen through one layer of official reality, is most of the way there.</p><p>The epistemological structure of the conspiracy theory is identical to the structure of spiritual awakening. In both cases, there is a surface reality that most people accept unthinkingly, and a deeper truth accessible only to those willing to question, to seek, to undergo the discomfort of knowing. The content differs. The initiatory logic is the same.</p><p>David Icke is useful here not because he's important but because his trajectory is so legible. Green Party spokesman. New Age healer. Shape-shifting lizard conspiracy theorist. Figure whose audiences now overlap substantially with the explicit far right. The antisemitism<a><sup>[6]</sup></a> of his cosmology — a hidden elite of inhuman beings controlling the world — was structurally present in the conspiracy framework from the beginning. The lizards were always a metaphor. The question was always what for.</p><hr /><p>In the Third Reich, Heinrich Himmler ran organic farms at the concentration camps. The SS had strict anti-vivisection laws. Walther Darré, Hitler's Agriculture Minister, built an ideology called <em>Blut und Boden</em> — Blood and Soil — around the mystical connection between the German peasant and the German land. The Nazi regime was, in significant respects, an ecological movement. It romanticised the natural, the pure, the uncorrupted.</p><p>It wanted to get back to the garden.</p><p>This is not a gotcha. It is not an attempt to smear environmentalism by association, or to suggest that everyone who has ever wanted to live closer to the land is a secret fascist. I’m a member of the Green Party, and the environment is something I care about deeply.</p><p>But it is a data point about what purity logic does when it is given political power and stripped of ethical constraint. The obsession with contamination — of the body, the land, the race, the culture — follows its own logic to its own conclusions. Those conclusions, historically, are not good.</p><p>The line from the organic farm to the death camp is not straight. It requires many other things to be true simultaneously. But the fact that it is possible to draw the line at all should give us pause, every time we find ourselves in the presence of someone who is very, very concerned with purity — of whatever kind.</p><hr /><p>Jello Biafra updated the song in 1980, after Ronald Reagan won the election. He replaced Jerry Brown with Reagan in the lyrics and re-recorded it. He updated it again when Arnold Schwarzenegger became Governor of California in 2003. The same song, again and again because the same <em>type</em> keeps appearing — the figure who combines cultural authority with authoritarian impulse, who has transcended ordinary limitation and would like to help you do the same, at gunpoint if necessary.</p><p>The type has been updated for the present moment. It no longer wears a kaftan, Zen robes or cowboy boots. He wears a black T-shirt and talks about first principles and rational thinking and the need to be <em>based</em>. He has a net worth that he regards as evidence of its own superior cognition. He is building a rocket, or buying a social media platform, or funding a political movement that would, if successful, remove the democratic constraints that prevent the most capable people from running things properly.</p><p>He believes, with complete sincerity, that he is one of the good guys.</p><p>The Zen fascist always does.</p><hr /><p><em>"We will make the future California's dream / California Über Alles"</em></p><p>The dream is still being made. The dreamers now have more money than most countries, direct access to the levers of state power, and a philosophy that tells them their dominance is not exploitation but evolution.</p><p>The granola became the brown rice became Huel became blood and soil. The encounter group became the est weekend became the biohacking protocol became the cognitive elite became the reaction. The Whole Earth became the platform became the firehose became the feed, and somewhere in the feed, the purity logic is still running, clean and patient, waiting for the next person to decide that they have woken up. That they are <em>clean</em>.</p><p>Joni Mitchell watched Woodstock on a hotel television and wrote a song of such aching beauty that five decades later it can still make you cry. It makes me cry, sometimes. She meant every word. She wasn't wrong about the stardust — we are, literally, made of it. She wasn't wrong about the garden — something has been lost, some connection to the world we actually live in rather than the screens we've replaced it with.</p><p>But the logic she was swimming in, the logic everyone was swimming in, was older and more dangerous than any of them knew. Purity doesn't announce itself. It arrives as poetry. It arrives as someone's hope.</p><p>Jello Biafra was writing a joke about a California politician.</p><p>He was also writing a warning about a kind of person.</p><p>That kind of person, today, is doing very well for themselves indeed.</p><hr /><ol><li>I should make this clear up front: when I talk in this essay about “purity politics”, what I’m <em>not</em> talking about the kind of instant condemnation that happens on social media platforms (Bluesky, I am looking at you). That’s interesting, but it’s not what I’m interested in <strong>right now.</strong> <a>↩︎</a></li>
<li>The same is true of that most popular of authors with the hippies, JJR Tolkien. The Shire is Eden, the garden. The orcs are the products of industry, literally things which were made. Michael Moorcock is excellent on this. <a>↩︎</a></li>
<li>Despite being a classic TLA (three letter acronym) est is never capitalised. <a>↩︎</a></li>
<li>I’m being a little simplistic here. est’s core concept was responsibility, but Erhard defined it in a specific, almost Zen way: you are the "source" of your experience. Not that you caused your circumstances in a simple causal chain, but that your relationship to your circumstances is itself a choice. The suffering isn't your fault in the sense of being a moral failing — it is your fault in the sense that you are choosing to experience it as suffering rather than as something else. <a>↩︎</a></li>
<li>Which, ironically, was a trans allegory written and directed by two trans women. <a>↩︎</a></li>
<li>Is Icke really an antisemite? I remember reading something about how Louis Theroux followed him around for a documentary, and Icke was denied entry to Canada because his claim that the world was ruled by lizard people was seen as coded antisemitism. Theroux explained that no, the lizard people weren’t Jews - he really did believe the world was ruled by actual lizards. But, that cute story aside, yes, Icke probably is an antisemite. <a>↩︎</a></li>
</ol>]]></description>
      <link>https://www.ianbetteridge.com/zen-fascist-wi/</link>
      <guid>https://www.ianbetteridge.com/zen-fascist-wi/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How to Run Local LLMs with Claude Code | Unsloth Documentation]]></title>
      <description><![CDATA[]]></description>
      <link>https://unsloth.ai/docs/basics/claude-code</link>
      <guid>https://unsloth.ai/docs/basics/claude-code</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Daring Fireball: The MacBook Neo]]></title>
      <description><![CDATA[<p>Just over a decade ago, <a href="https://daringfireball.net/2015/09/the_iphones_6s#:~:text=BENCHMARKS">reviewing the then-new iPhones 6S</a>, I could tell which way the silicon wind was blowing. Year-over-year, the A9 CPU in the iPhone 6S was 1.6× faster than the A8 in the iPhone 6. Impressive. But what really struck me was comparing the 6S’s GeekBench scores to MacBooks. The A9, in 2015, benchmarked comparably to a two-year-old MacBook Air from 2013. More impressively, it <em>outperformed the then-new no-adjective 12-inch MacBook in single-core performance</em> (by a factor of roughly 1.1×) and was only 3 percent slower in multi-core. That was a comparison to <a href="https://www.apple.com/newsroom/2015/03/09Apple-Unveils-All-New-MacBook/">the base $1,300 model MacBook with a 1.1 GHz dual-core Intel Core M processor</a>, not the $1,600 model with a 1.2 GHz Core M. But, still — the iPhone 6S outperformed a brand-new $1,300 MacBook, and drew even with a $1,600 model. I called that “astounding”. The writing was clearly on the wall: the future of the Mac seemed destined to move from Intel’s x86 chips to Apple’s own ARM-based chips.</p><p>Here we are today, over five years after the debut of Apple’s M-series chips, and we now have <a href="https://www.apple.com/newsroom/2026/03/say-hello-to-macbook-neo/">the MacBook Neo</a>: a $600 laptop that uses the A18 Pro, literally the same SoC as 2024’s iPhone 16 Pro models. It was clear right from the start of the Apple Silicon transition that Apple’s M-series chips were vastly superior to x86 — better performance-per-watt, better performance period, the innovative (and still unmatched, five years later) <a href="https://developer.apple.com/videos/play/wwdc2020/10686/">unified memory architecture</a> — but the MacBook Neo proves that Apple’s A-series chips are powerful enough for an excellent consumer MacBook.</p>
<p>I think the truth is that Apple’s A-series chips have been capable of credibly powering Macs for a long time. The <a href="https://en.wikipedia.org/wiki/Developer_Transition_Kit">Apple Silicon developer transition kits</a>, from the summer of 2020, were Mac Mini enclosures running A12Z chips that were originally designed for iPad Pros.<sup id="fnr1-2026-03-10"><a href="#fn1-2026-03-10">1</a></sup> But I think Apple could have started using A-series chips in Macs even before that. It would have been credible, but with compromises. By waiting until now, the advantages are simply overwhelming. You cannot buy an x86 PC laptop in the $600–700 price range that competes with the MacBook Neo on any metric — performance, display quality, audio quality, or build quality. And certainly not software quality.</p>
<p>The original iPhone in 2007 was the most amazing device I’ve ever used. It may well wind up being the most amazing device I ever <em>will</em> use. It was ahead of its time in so many ways. But a desktop-class computer, performance-wise, it was not. Two decades is a long time in the computer industry, and nothing proves that more than Apple’s “phone chips” overtaking Intel’s x86 platform in every measurable metric — they’re faster, cooler, smaller, and perhaps even cost less. And they certainly don’t cost more.</p>
<p>I’ve been testing a citrus-colored $700 MacBook Neo<sup id="fnr2-2026-03-10"><a href="#fn2-2026-03-10">2</a></sup> — the model with Touch ID and 512 GB storage — since last week. I set it up new, rather than restoring my primary MacOS work setup from an existing Mac, and have used as much built-in software, with as many default settings, as I could bear. I’ve only added third-party software, or changed settings, as I’ve needed to. And I’ve been using it for as much of my work as possible. I expected this to go well, but in fact, the experience has vastly exceeded my expectations. Christ almighty I don’t even have as many complaints about running MacOS 26 Tahoe (which the Neo requires) as I thought I would.</p>
<p>It’s never been a good idea to evaluate the performance of Apple’s computers by tech specs alone. That’s exemplified by the experience of using a Neo. 8 GB of RAM is not a lot. And I love me my RAM — my personal workstation remains a 2021 M1 Max MacBook Pro with 64 GB RAM (the most available at the time). But just using the Neo, without any consideration that it’s memory limited, I haven’t noticed a single hitch. I’m not quitting apps I otherwise wouldn’t quit, or closing Safari tabs I wouldn’t otherwise close. I’m just working — with an even dozen apps open as I type this sentence — and everything feels snappy.</p>
<p>Now, could I run up a few <em>hundred</em> open Safari tabs on this machine, like I do on my MacBook Pro, without feeling the effects? No, probably not. But that’s abnormal. In typical productivity use, the Neo isn’t merely fine — it’s good.</p>
<p>The display is bright and crisp. At 500 maximum nits, the specs say it’s as bright as a MacBook Air. In practice, that feels true. (500 nits also matches the maximum SDR brightness of my personal M1 MacBook Pro.) Sound from the side-firing speakers is very good — loud and clear. I’d say the sound seems too good to be true for a $600 laptop. Battery life is long (and I’ve done almost all my testing while the Neo is unplugged from power). The keyboard feels exactly the same as what I’m used to, except that because the key caps are brand new, it feels even better than the keyboard on my own now-four-years-old MacBook Pro, the most-used key caps on which are <a href="https://mjtsai.com/blog/2024/05/08/shiny-macbook-keys/">now a little slick</a>.</p>
<p>And the trackpad. Let me sing the praises of the MacBook Neo’s trackpad. The Neo’s trackpad exemplifies the Neo as a whole. Rather than sell old components at a lower price — as Apple had been doing, allowing third-party resellers like Walmart to sell the 8 GB M1 MacBook Air from 2020 at sub-$700 prices <a href="https://daringfireball.net/linked/2024/03/15/macbook-air-walmart">starting two years ago</a> — the Neo is designed from the ground up to be a low-cost MacBook.</p>
<p>A decade ago, Apple began switching from trackpads with mechanical clicking mechanisms to Magic Trackpads, where clicks are simulated via haptic feedback (in Apple’s parlance, the Taptic Engine). And, with Magic Trackpads, you can use Force Touch — a hard press — to perform special actions. By default, if “Force Touch and haptic feedback” is enabled on a Mac with a Magic Trackpad, a hard Force Touch press will perform a Look Up — e.g., do it on a word in Safari and you’ll get a popover with the Dictionary app’s definition for that word. It’s a shortcut to the “Look Up in Dictionary” command in the contextual menu, which is also available <a href="https://support.apple.com/en-us/102650">via the keyboard shortcut Control-Command-D</a> to look up whatever text is currently selected, or that the mouse pointer is currently hovering over — standard features that work in all proper Mac apps.</p>
<p>The Neo’s trackpad is mechanical. It actually clicks, even when the machine is powered off.<sup id="fnr3-2026-03-10"><a href="#fn3-2026-03-10">3</a></sup> Obviously this is a cost-saving measure. But the Neo’s trackpad doesn’t feel cheap in any way. You can click it anywhere you want — top, bottom, middle, corner — and the click feels right. Multi-finger <a href="https://support.apple.com/en-us/102482">gestures</a> (most commonly, two-finger swipes for scrolling) — just work. Does it feel as nice as a Magic Trackpad? No, probably not. But I keep forgetting there’s anything at all different or special about this trackpad. It just feels normal. That’s unbelievable. The “Force Touch and haptic feedback” option is missing in the Trackpad panel in System Settings, so you might miss that feature if you’re used to it. But for anyone who isn’t used to that Magic Trackpad feature — which includes anyone who’s never used a MacBook before (perhaps the primary audience for the Neo), along with most casual longtime Mac users (which is probably the secondary audience) — it’s hard to say there’s anything they’d even notice that’s different about this trackpad than the one in the MacBook Air, other than the fact that it’s a little bit smaller. But it’s only smaller in a way that feels proportional to the Neo’s slightly smaller footprint compared to the Air. It’s a cheaper trackpad that doesn’t feel at all cheap. Bravo!</p>
<h2>So What’s the Catch?</h2>
<p>You can use <a href="https://www.apple.com/mac/compare/?modelList=MacBook-Neo-A18-Pro,MacBook-Air-M5,MacBook-Air-M1">this Compare page at Apple’s website</a> (archived, for posterity, <a href="https://daringfireball.net/misc/2026/03/MacBook-Neo-(A18-Pro)-vs-MacBook-Air-(M5)-vs-MacBook-Air-(M1).pdf">as a PDF here</a>) to see the full list of what’s missing or different on the Neo, compared to the current M5 MacBook Air (which now starts at $1,100) and the 5-year-old M1 MacBook Air (so old it still sports the Intel-era wedge shape) that Walmart had been selling for $600–650. Things I’ve noticed, that bothered me, personally:</p>
<ul><li>The Neo lacks an ambient light sensor. It still offers an option in System Settings → Display to “Automatically adjust brightness”, which setting is on by default, but I have no idea how it works without an ambient light sensor. However it works, it doesn’t work well. As the lighting conditions in my house have changed — from day to night, overcast to sunny — I’ve found myself adjusting the display brightness manually. I only realized when I started adjusting the brightness on the Neo manually that I more or less haven’t adjusted the brightness manually on a MacBook in years. Maybe a decade. I’m not saying I <em>never</em> adjust the brightness on a MacBook Air or Pro, but I do it so seldomly that I had no muscle memory at all for which F-keys control brightness. After a few days using the Neo, I know exactly where they are: F1 and F2.</li>
</ul><p>And, uh, that’s it. That’s the one catch that’s annoyed me over the six days I’ve been using the Neo as my primary computer for work and for reading. Once or twice a day I need to manually bump the display brightness up or down.  That’s a crazily short list. One item, and it’s only a mild annoyance.</p>
<p>There are other things missing that I’ve noticed, but that I haven’t minded. The Neo doesn’t have a hardware indicator light for the camera. The indication for “camera in use” is only in the menu bar. There’s a privacy/security implication for this omission. According to Apple, the hardware indicator light for camera-in-use on MacBooks, iPhones, and iPads <a href="https://news.ycombinator.com/item?id=23799821">cannot be circumvented by software</a>. If the camera is on, that light comes on, and no software can disable it. Because the Neo’s only camera-in-use indicator is in the menu bar, that seems obviously possible to circumvent via software. Not a big deal, but worth being aware of.</p>
<p>The Neo’s webcam doesn’t offer Center Stage or Desk View. But personally, I never take advantage of Center Stage or Desk View, so I don’t miss their absence. Your mileage may vary. But the camera is 1080p and to my eyes looks pretty good. And I’d say it looks damn good for a $600 laptop.</p>
<p>The Neo has no notch. Instead, it has a larger black bezel surrounding the entire display than do the MacBook Airs and Pros. I consider this an advantage for the Neo, not a disadvantage. The MacBook notch has not grown on me, and the Neo’s display bezel doesn’t bother me at all.</p>
<p>And there’s the whole thing with the second USB-C port only supporting USB 2 speeds. That stinks. But if Apple could sell a one-port MacBook a decade ago, they can sell one with a shitty second port today. I’ll bet this is one of the things that will be improved in the second generation Neo, but it’s not something that would keep me from recommending this one — or even buying one myself — today. If you know you need multiple higher-speed USB ports (or Thunderbolt), you need a MacBook Air or Pro.</p>
<p>The Neo ships with a measly 20-watt charger in the box — the same rinky-dink charger that comes with iPad Airs. I wish it were 30 watts (which is what came with the M1 MacBook Air), but maybe we’re lucky it comes with a charger at all. The Neo charges faster if you plug it into a more powerful power adapter, in either USB-C port.<sup id="fnr4-2026-03-10"><a href="#fn4-2026-03-10">4</a></sup> The USB-C cable in the box is white, not color-matched to the Neo, and it’s only 1.5 meters long. MacBook Airs and Pros ship with 2-meter MagSafe cables. Again, though: $600!</p>
<h2>The Weighty Issue on My Mind</h2>
<p>The Neo is not a svelte ultralight. It weights 2.7 pounds (1.23 kg) — exactly the same as the 13-inch M5 MacBook Air. The Neo, with a 13.0-inch display, has a smaller footprint than the 13.6-inch Air, but the Air is thinner. I don’t know if this is a catch though. It’s just the normal weight for a smaller-display Mac laptop. The decade-ago MacBook “One”, on the other hand, was a design statement. <a href="https://support.apple.com/en-us/112442">It weighed just a hair over 2 pounds</a> (0.92 kg), and tapered from 1.35 cm to just 0.35 cm in thickness. The Neo is 1.27 cm thick, and the M5 Air is 1.13 cm. In fact, the extraordinary thinness of the 2015 MacBook might have necessitated the invention of the haptics-only Magic Trackpad. The Magic Trackpad first appeared on that MacBook and the early 2015 MacBook Pros — it was nice-to-have for the MacBook Pros, but might have been the only trackpad that would fit in the front of the MacBook One’s tapered case.</p>
<p>If I had my druthers, Apple would make a new svelte ultralight MacBook. Not instead of the Neo, but in addition to the Neo. Apple’s inconsistent use of the name “Air” makes this complicated, but the MacBook Neo is obviously akin to the iPhone 17e; the MacBook Air is akin to the iPhone 17 (the default model for most people); the MacBook Pros are akin to the iPhone 17 Pros. I wish Apple would make a MacBook that’s akin to the iPhone Air — crazy thin and surprisingly performant.</p>
<p>The biggest shortcoming of the decade-ago MacBook “One”, aside from the baffling decision to include just one USB-C port that was also its only means of charging, was the shitty performance of Intel’s Core M chips. Those chips were small enough and low-power enough to fit in the MacBook’s thin and fan-less enclosure, but they were slow as balls. It was a huge compromise for a laptop that carried a somewhat premium price. Today, performance, performance-per-watt, and physical chip size are all solved problems with Apple Silicon. I’d consider paying double the price of the Neo for a MacBook with similar specs (but more RAM and better I/O) that weighed 2.0 pounds or less. I’d buy such a MacBook not to replace my 14-inch MacBook Pro, but to replace my 2018 11-inch iPad Pro as my “carry around the house” secondary computer.<sup id="fnr5-2026-03-10"><a href="#fn5-2026-03-10">5</a></sup></p>
<p>As it stands, I might buy a Neo for that same purpose, 2.7-pound weight be damned. iPad Pros, encased in Magic Keyboards, are expensive and heavy. So are iPad Airs. My 2018 iPad Pro, in its Magic Keyboard case, weighs 2.36 pounds (1.07 kg). That’s the 11-inch model, with a cramped less-than-standard-size keyboard. I’m much happier with this MacBook Neo than I am doing anything on that iPad. Yes, my iPad is old at this point. But replacing it with a new iPad Pro would require a new Magic Keyboard too. For an iPad Pro + Magic Keyboard, that combination starts at $1,300 for 11-inch, $1,650 for 13-inch. If I switched to iPad Air, the cost would be $870 for 11-inch, $1,120 for 13-inch. The 13-inch iPads, when attached to Magic Keyboards, weigh slightly <em>more</em> than a 2.7-pound 13-inch MacBook Neo. The 11-inch iPads, with keyboards, weigh about 2.3 pounds. Why bother when I find MacOS way more enjoyable and productive? My three-device lifestyle for the last decade has been a MacBook Pro (anchored to a Studio Display at my desk at home, and in my briefcase when travelling); my iPhone; and an iPad Pro with a Magic Keyboard for use around the rest of the house. This last week testing the MacBook Neo, I haven’t touched my iPad once, and I haven’t once wished this Neo were an iPad. And there were many times when I was very happy that it was a Mac.</p>
<p>And I can buy one, just like this one, for $700. That’s $170 less than an 11-inch iPad Air and Magic Keyboard. And the Neo comes with a full-size keyboard and runs MacOS, not a version of iOS with a limited imitation of MacOS’s windowing UI. I am in no way arguing that the MacBook Neo is an iPad killer, but it’s a splendid iPad alternative for people like me, who don’t draw with a Pencil, do type with a keyboard, and just want a small, simple, highly portable and highly capable computer to use around the house. The MacBook Neo is going to be a great first Macintosh for a lot of people switching from PCs. But it’s also going to be a great <em>secondary</em> Mac for a lot of longtime Mac users with expensive desktop setups for their main workstations — like me.</p>
<p>The Neo crystallizes the post-Jony Ive Apple. The MacBook “One” was a design statement, and a much-beloved semi-premium product for a relatively small audience. The Neo is a mass-market device that was conceived of, designed, and engineered to expand the Mac user base to a larger audience. It’s a design statement too, but of a different sort — emphasizing practicality above all else. It’s just a goddamn lovely tool, and fun too.</p>
<p>I’ll just say it: I think I’m done with iPads. Why bother when Apple is now making a crackerjack Mac laptop that starts at just $600? May the MacBook Neo live so long that its name becomes inapt.</p>
<div class="footnotes">
<hr /><ol><li id="fn1-2026-03-10">
<p><a href="https://daringfireball.net/2026/03/599_not_a_piece_of_junk_macbook_neo">When I wrote last week</a> that the MacBook Neo is the first product from Apple with an A-series chip sporting more than one USB port — addressing complaints that the Neo’s second USB-C port only supports USB 2.0 speeds — a few readers pointed to <a href="https://en.wikipedia.org/wiki/Developer_Transition_Kit">the Apple Silicon developer transition kits</a>. Those machines had two USB-C 3.1 ports, two USB-A 3.0 ports, <em>and</em> an HDMI port. But Apple didn’t sell those as a product — developers borrowed them from Apple, and <a href="https://www.macrumors.com/2021/02/05/apple-dtk-credit-for-developers-increased/">Apple wanted them back</a> soon after the first actual Apple Silicon Macs shipped. If Apple had sold them, they would have cost more than $600. Those extra I/O ports involved significant engineering outside the A12Z SoC. <a href="#fnr1-2026-03-10" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩︎</a></p>
</li>
<li id="fn2-2026-03-10">
<p>The Neo’s citrus is a beguiling colorway. Everyone I’ve shown it to likes it. But is it a green-ish yellow, or a yellow-ish green? In daylight, it looks more like a green-ish yellow. But at nighttime, it looks more like a yellow-ish green. By default, the MacOS accent color in System Settings → Appearance defaults to a color that matches the Neo’s hardware — a fun trick Apple has been <a href="https://512pixels.net/2012/12/imac/">using for decades</a>. For citrus, that special accent color <a href="https://daringfireball.net/misc/2026/03/macbook-neo-citrus-appearance-color.png">looks more green than yellow to me</a>. <a href="#fnr2-2026-03-10" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩︎︎</a></p>
</li>
<li id="fn3-2026-03-10">
<p>The haptic “clicks” with a Magic Trackpad are so convincingly real that it feels <em>really</em> weird when you try to click the trackpad on a powered-off MacBook Air or Pro, or a standalone Magic Trackpad that’s turned off, and ... nothing happens. Not even the slightest hint of a click. Just totally inert. It’s gross, like poking a dead pet. <a href="#fnr3-2026-03-10" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">↩︎︎</a></p>
</li>
<li id="fn4-2026-03-10">
<p>My favorite power adapter is <a href="https://nomadgoods.com/products/ac-adapter-65w-usb-c-slim">this $55 two-port 65-watt “slim” charger from Nomad</a>. It’s small, lightweight, and the lay-flat design helps it stay connected to loose wall outlets in hotels and public spaces like airports and coffee shops. Nomad also sells a smaller 40-watt model with only one port, and a larger 100-watt model. But to me the 65-watt model hits the sweet spot. The link above goes to Nomad’s website; <a href="https://www.amazon.com/NOMAD-65W-Slim-Power-Adapter/dp/B0CYP6KPPB/?tag=df-amzn-20">here’s a make-me-rich affiliate link to it at Amazon</a>. <a href="#fnr4-2026-03-10" class="footnoteBackLink" title="Jump back to footnote 4 in the text.">↩︎︎</a></p>
</li>
<li id="fn5-2026-03-10">
<p>One advantage to the 2.7-pound Neo compared to the decade-ago 2.0-pound MacBook “One” — you can lift the lid on the Neo with one hand and it just opens. With the old MacBook, the base was so light that the whole thing tended to lift when you just wanted to open the display. <a href="#fnr5-2026-03-10" class="footnoteBackLink" title="Jump back to footnote 5 in the text.">↩︎︎</a></p>
</li>
</ol></div>]]></description>
      <link>https://daringfireball.net/2026/03/the_macbook_neo</link>
      <guid>https://daringfireball.net/2026/03/the_macbook_neo</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Amazon launches its healthcare AI assistant on its website and app]]></title>
      <description><![CDATA[<p id="speakable-summary" class="wp-block-paragraph">Amazon <a href="https://www.aboutamazon.com/news/retail/amazon-health-ai-agent-one-medical" target="_blank" rel="noreferrer noopener nofollow">announced</a> on Tuesday that it’s expanding access to its healthcare AI assistant to its website and app. The assistant, called Health AI, was previously only available on the app for One Medical, the healthcare company <a href="https://techcrunch.com/2022/07/21/amazon-is-buying-primary-care-tech-provider-one-medical-for-3-9b/" target="_blank" rel="noreferrer noopener">Amazon acquired for $3.9 billion in 2023</a>.</p><p class="wp-block-paragraph">Health AI can answer questions, explain health records, manage prescription renewals, book appointments, and more. Users don’t need to be Prime subscribers or One Medical members to use the assistant, Amazon says.</p><p class="wp-block-paragraph">Amazon says that while Health AI can answer general health questions without having access to an individual’s medical information, it’s designed to serve as a personalized health assistant that can offer more tailored guidance and take actions, such as connecting you with healthcare professionals and treatments.</p><p class="wp-block-paragraph">Of course, there are risks associated with sharing your health information with AI, and <a href="https://hai.stanford.edu/news/be-careful-what-you-tell-your-ai-chatbot" target="_blank" rel="noreferrer noopener nofollow">researchers</a> are <a href="https://medschool.duke.edu/stories/hidden-risks-asking-ai-health-advice" target="_blank" rel="noreferrer noopener nofollow">warning against</a> doing so, cautioning that companies are pulling user conversations for training.</p><p class="wp-block-paragraph">Amazon said in its announcement that it trains “Health AI models on abstracted patterns without directly identifying information.” For example, if multiple patients ask about medication interactions, Amazon says it might use these patterns, while keeping patient names private, to improve how Health AI responds to similar questions.</p><p class="wp-block-paragraph">The company also said that all interactions with Health AI happen within a HIPAA-compliant environment, and that conversations are protected by “encryption and strict access controls.” Amazon told TechCrunch in an email that only authorized personnel who need access to perform specific HIPAA-allowed job functions, such as service maintenance, clinical quality assurance, and addressing technical issues, can view conversation data.</p><p class="wp-block-paragraph">With a user’s permission, Health AI gets access to their health information through the Health Information Exchange, which is the nationwide secure system for sharing patient medical data.</p><div class="wp-block-techcrunch-inline-cta inline-cta__wrapper"><p>Techcrunch event</p><div class="inline-cta__content"><div class="inline-cta__header-container"><div class="inline-cta__header-container-mobile"><p>Offer ends March 13.</p></div></div><p>San Francisco, CA | October 13-15, 2026</p><p><a data-ctatext="REGISTER NOW" data-destinationlink="https://techcrunch.com/events/tc-disrupt-2026/?utm_source=tc&amp;utm_medium=ad&amp;utm_campaign=disrupt2026&amp;utm_content=tc_inline_eb&amp;promo=tc_inline_eb&amp;display=" data-event="button" class="wp-block-button__link wp-element-button" href="https://techcrunch.com/events/tc-disrupt-2026/?utm_source=tc&amp;utm_medium=ad&amp;utm_campaign=disrupt2026&amp;utm_content=tc_inline_eb&amp;promo=tc_inline_eb&amp;display=" target="_blank" rel="noreferrer noopener">REGISTER NOW</a></p></div></div><p class="wp-block-paragraph">Health AI can then interpret your lab results, diagnoses, and medical records to provide accurate, personalized answers about your symptoms and medication, Amazon says.</p><figure class="wp-block-image aligncenter size-large"><img height="383" width="680" src="https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?w=680" alt="" class="wp-image-3101156" srcset="https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg 1320w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=150,84 150w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=300,169 300w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=768,432 768w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=680,383 680w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=1200,675 1200w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=1280,720 1280w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=430,242 430w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=720,405 720w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=900,507 900w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=800,450 800w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=668,376 668w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=666,375 666w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=1096,617 1096w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=708,399 708w, https://techcrunch.com/wp-content/uploads/2026/03/health-ai.jpeg?resize=50,28 50w" sizes="auto, (max-width: 680px) 100vw, 680px" /><figcaption class="wp-element-caption"><strong>Image Credits:</strong>Amazon</figcaption></figure><p class="wp-block-paragraph">If you need professional care, Health AI can connect you to a One Medical provider. Prime members in the U.S. using Health AI receive up to five free direct-message care consultations with a One Medical provider for over 30 common conditions, including cold and flu, allergies, acid reflux, pink eye, UTIs, erectile dysfunction, anti-aging skin care, hair loss, and more. Non-Prime members can connect with One Medical providers through Amazon’s pay-per-visit option.</p><p class="wp-block-paragraph">Users can sign up for Health AI on the <a href="https://amazon.com/health-ai" target="_blank" rel="noreferrer noopener nofollow">Amazon Health page</a>. As Amazon expands access, users will receive an email once they are able to access the assistant.</p><p class="wp-block-paragraph">Once users have access, they need to create a or sign in to their personal Amazon Health profile. They can then start a conversation by typing their health question to Health AI on Amazon.com or in the Amazon app.</p><p class="wp-block-paragraph">Users can ask questions like “Can you explain my recent cholesterol results and what they mean for me?” or “I’m feeling congested and have a sore throat. What should I do?”</p><p class="wp-block-paragraph">Amazon’s expansion of Health AI comes as popular AI services have quickly moved into the healthcare space. In January, OpenAI released <a href="https://techcrunch.com/2026/01/07/openai-unveils-chatgpt-health-says-230-million-users-ask-about-health-each-week/" target="_blank" rel="noreferrer noopener">ChatGPT Health</a>, a version of its chatbot tailored to answer health questions. A week later, Anthropic announced its own healthcare-focused product, <a href="https://techcrunch.com/2026/01/12/anthropic-announces-claude-for-healthcare-following-openais-chatgpt-health-reveal/" target="_blank" rel="noreferrer noopener">Claude for Healthcare</a>.</p><p class="wp-block-paragraph"><em>Update 03/11/2026: Updated with additional information regarding access controls.</em></p>]]></description>
      <link>https://techcrunch.com/2026/03/10/amazon-launches-its-healthcare-ai-assistant-on-its-website-and-app/</link>
      <guid>https://techcrunch.com/2026/03/10/amazon-launches-its-healthcare-ai-assistant-on-its-website-and-app/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[U+237C ⍼ is Azimuth · Jonathan Chan]]></title>
      <description><![CDATA[<div class="image-wrapper"><img width="60%" src="https://ionathan.ch/assets/images/angzarr/all%20glyphs.svg" title="" alt="" /></div><p><small><em><a href="https://ionathan.ch/2022/04/09/angzarr.html">Part 1</a> · <a href="https://ionathan.ch/2023/06/06/angzarr.html">Part 2</a> · <a href="https://ionathan.ch/2024/01/27/angzarr.html">Part 3</a> · <a href="https://ionathan.ch/2024/08/07/angzarr.html">Part 4</a> · <a href="https://ionathan.ch/2026/02/16/angzarr.html">Part 5</a> ← you are here</em></small></p><p>One year ago, on 28 February 2025, Wikipedia user <a href="https://en.wikipedia.org/w/index.php?title=Angzarr&amp;diff=prev&amp;oldid=1278225132">Moyogo updated the page for Angzarr</a> with a citation to the type foundry H. Berthold AG’s 1950 symbol catalogue listing ⍼ as <em>Azimut, Richtungswinkel</em>, or “azimuth”, “direction angle”. Mystery solved!</p><div class="image-wrapper"><img width="60%" src="https://ionathan.ch/assets/images/angzarr/Registerprobe%20039.jpg" title="6039 ⍼ 4 8039 ⍼ 6 10 039 ⍼ 8 12 039 ⍼ 10 L Azimut, Richtungswinkel" alt="6039 ⍼ 4 8039 ⍼ 6 10 039 ⍼ 8 12 039 ⍼ 10 L Azimut, Richtungswinkel" /></div><p>Fonts in Use lists links to <a href="https://fontsinuse.com/foundry/159/berthold">archived catalogues by Berthold</a>. The above scan is from the <a href="https://berlin.museum-digital.de/singleimage?imagenr=101440">1950 Zeichenprobe</a> (symbol catalogue) on page 7. Copies of the Schriftprobe (font catalogue) from <a href="https://berlin.museum-digital.de/singleimage?imagenr=110867">1949</a>, <a href="https://berlin.museum-digital.de/singleimage?imagenr=123825">1951</a>, and <a href="https://berlin.museum-digital.de/singleimage?imagenr=124046">1952</a> all show on page 104 the same glyph and sizes, albeit without the descriptor name.</p><div class="image-wrapper"><img width="60%" src="https://ionathan.ch/assets/images/angzarr/Schriftprobe%20039.jpg" title="6039 ⍼ 8039 ⍼ 10 039 ⍼ 12 039 ⍼ L" alt="6039 ⍼ 8039 ⍼ 10 039 ⍼ 12 039 ⍼ L" /></div><p>⍼ does <em>not</em> appear in the <a href="https://berlin.museum-digital.de/singleimage?imagenr=99346">1946 Registerprobe</a>, nor in earlier <a href="https://digital.staatsbibliothek-berlin.de/werkansicht?PPN=PPN1767647026&amp;PHYSID=PHYS_0415">1909</a> and <a href="https://digital.staatsbibliothek-berlin.de/werkansicht?PPN=PPN1767697953&amp;PHYSID=PHYS_0271">1900</a> catalogues. For convenience, I’ve extracted full-page scans below for where it appears — and where I feel it would appear, but doesn’t.</p><div class="carousel"><img class="c1" src="https://ionathan.ch/assets/images/angzarr/Berthold%201950.jpg" alt="Mathematische Zeichen, p. 7" title="Mathematische Zeichen, p. 7" />Zeichenprobe (1950), p. 7 (yes ⍼)<img class="c2" src="https://ionathan.ch/assets/images/angzarr/Berthold%201949.jpg" alt="Mathematische Zeichen, p. 104" title="Mathematische Zeichen, p. 104" />Schriftprobe (1949), p. 104 (yes ⍼)<img class="c3" src="https://ionathan.ch/assets/images/angzarr/Berthold%201946.jpg" alt="Mathematische Zeichen, p. 317" title="Mathematische Zeichen, p. 317" />Registerprobe (1946), p. 317 (no ⍼)<img class="c4" src="https://ionathan.ch/assets/images/angzarr/Berthold%201909.jpg" alt="Mathematische Zeichen, p. 415" title="Mathematische Zeichen, p. 415" />Hauptprobe (1909), p. 415 (no ⍼)<img class="c5" src="https://ionathan.ch/assets/images/angzarr/Berthold%201900.jpg" alt="Zeichen, p. 217" title="Zeichen, p. 217" />Schriftproben (1900), p. 217 (no ⍼)</div><p>A friend on Mastodon pointed out that the glyph ⍼ itself resembles the way a light ray passes through a <a href="https://en.wikipedia.org/wiki/Sextant">sextant</a> to measure an azimuth, with the right angle being a standard symbol for an angle in general. Wikipedia has a lovely illustration demonstrating how a sextant works to measure latitude of the sun. The same article has a photo of a captain using a sextant turned sideways to measure a horizontal angle.</p><div class="image-wrapper"><img width="60%" src="https://upload.wikimedia.org/wikipedia/commons/7/76/Using_sextant_swing.gif" title="Animation of the use of a marine sextant to measure the altitude of the sun" alt="Animation of the use of a marine sextant to measure the altitude of the sun" /></div>]]></description>
      <link>https://ionathan.ch/2026/02/16/angzarr.html</link>
      <guid>https://ionathan.ch/2026/02/16/angzarr.html</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Fediverse invitation | Stefan Bohacek]]></title>
      <description><![CDATA[<p>Over the years I’ve experimented with how to best explain and invite people into the fediverse. I’ve created <a href="https://jointhefediverse.net/">jointhefediverse.net</a> which introduces the concept of the fediverse, with links for further learning. I also wrote a <a href="https://stefanbohacek.com/blog/how-to-join-mastodon-and-the-fediverse/">guide centered around Mastodon</a>, a fediverse platform I am most familiar with, and another pair of guides, one aimed at <a href="https://stefanbohacek.com/blog/fediverse-an-overview-for-community-organizers/">community organizers</a>, and another for <a href="https://stefanbohacek.com/blog/fediverse-an-overview-for-government-agencies/">government agencies</a>.</p><p>I think all these work great for their intended audience, but I also believe that the most effective way to promote fediverse is through specific communities, as that removes the choice paralysis of having to pick a server to sign up on.</p><p>The other day I came across <a href="https://joinirc.at/">joinirc.at</a>. It’s such a clever way to onboard new users by linking to a specific <a href="https://en.wikipedia.org/wiki/IRC">IRC server</a>, and I just had to <span class="c2">steal</span> borrow the idea.</p><div class="wp-block-image"><figure class="aligncenter size-full"><a href="https://invite.jointhefediverse.net/?server=hachyderm.io"><picture><source srcset="https://stefanbohacek.com/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io.png.webp 1463w, https://stefanbohacek.com/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-250x141.png.webp 250w, https://stefanbohacek.com/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-700x395.png.webp 700w, https://stefanbohacek.com/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-768x433.png.webp 768w, https://stefanbohacek.com/wp-content/webp-express/webp-images/doc-root/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-120x68.png.webp 120w" sizes="(max-width: 1463px) 100vw, 1463px" type="image/webp" /><img width="1463" height="825" src="https://stefanbohacek.com/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io.png" alt="A screenshot of the invitation page titled 'Join the fediverse!' with a brief description of what the fediverse is and also a description of the Hachyderm,io server." class="wp-image-9153 webpexpress-processed" srcset="https://stefanbohacek.com/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io.png 1463w, https://stefanbohacek.com/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-250x141.png 250w, https://stefanbohacek.com/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-700x395.png 700w, https://stefanbohacek.com/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-768x433.png 768w, https://stefanbohacek.com/wp-content/uploads/2026/02/fediverse-invitation-screenshot-hachyderm-io-120x68.png 120w" sizes="(max-width: 1463px) 100vw, 1463px" /></picture></a></figure></div><p>The easiest way to use this page is to update the <code>server</code> parameter, for example:</p><pre>https://invite.jointhefediverse.net/?server=hachyderm.io</pre><a href="https://invite.jointhefediverse.net/?server=hachyderm.io&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>You can also customize the apps that get listed on this page by specifying their IDs. (<a href="https://github.com/stefanbohacek/fediverse-invite/blob/main/data/apps.json" data-type="link" data-id="https://github.com/stefanbohacek/fediverse-invite/blob/main/data/apps.json">Here’s the full list.</a> I know there are many more, I will be sure to keep adding them!)</p><pre>https://invite.jointhefediverse.net/?server=indieweb.social&amp;apps=1,2,5,7</pre><a href="https://invite.jointhefediverse.net/?server=indieweb.social&amp;apps=1,2,5,7&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>You can even change their order.</p><pre>https://invite.jointhefediverse.net/?server=theforkiverse.com&amp;apps=4,3,1,2</pre><a href="https://invite.jointhefediverse.net/?server=theforkiverse.com&amp;apps=4,3,1,2&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>And while these examples focus on Mastodon, you can promote any server. Here’s an invitation with a Pleroma server. (I am not sure if the apps are compatible with Pleroma, so please consider this just an example.)</p><pre>https://invite.jointhefediverse.net/?server=stereophonic.space&amp;apps=6,8</pre><a href="https://invite.jointhefediverse.net/?server=stereophonic.space&amp;apps=6,8&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>There is also a few extra keywords you can pass as the value for <code>apps</code>:</p><p>To list all apps:</p><pre>https://invite.jointhefediverse.net/?apps=all</pre><a href="https://invite.jointhefediverse.net/?apps=all&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>To list all apps for a specific platform, use one of the values <code>android</code>, <code>ios</code>, or <code>web</code>. Example:</p><pre>https://invite.jointhefediverse.net/?apps=android</pre><a href="https://invite.jointhefediverse.net/?apps=android&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>And you can get really nerdy with <code>retro</code>.</p><pre>https://invite.jointhefediverse.net/?apps=retro</pre><a href="https://invite.jointhefediverse.net/?apps=retro&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>And finally, you can pass up to four IDs of starter packs from <a href="https://fedidevs.com/starter-packs/">Fedidevs</a> to include them on the page.</p><pre>https://invite.jointhefediverse.net/?starterpacks=NjQ5,ODI5,OTIw,ODY4</pre><a href="https://invite.jointhefediverse.net/?starterpacks=NjQ5,ODI5,OTIw,ODY4&amp;lang=en-us" class="btn btn-primary" target="_blank">Open link</a><p>I consider this an experiment and very much intend to further play with the idea. I am pretty happy with some of the little details that went into making this invitation page simple and usable, for example, the “popular accounts” link carries over the server domain, which allows the profiles to be open directly on the server, removing the need to look each account up, or even having to explain that’s how account discovery works. (Kudos to <a href="https://gardenstate.social/@stefan">Stefan Hayden</a>, the creator of this list, for making that possible.)</p><p>Feedback is <a href="https://stefanbohacek.com/contact/">very welcome</a>, but also, feel free to create your own invitation page inspired by this project!</p>]]></description>
      <link>https://stefanbohacek.com/project/fediverse-invitation/</link>
      <guid>https://stefanbohacek.com/project/fediverse-invitation/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Pencil – Design Mode for Cursor]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.pencil.dev/</link>
      <guid>https://www.pencil.dev/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Gochujang Caramel Cookies Recipe - NYT Cooking]]></title>
      <description><![CDATA[<div class="recipebody_body-container__GfPut">
<hr class="divider_divider__PSzI_ recipebody_ingredients-horizontal-rule__o77oZ divider_thick__Jk7ex" /><div class="recipebody_ingredients-block__OFg5G ingredients_ingredients__FLjsC">
<div class="ingredients_recipeYield__DN65p">Yield:About 8 large cookies</div>
<ul><li class="pantry--ui ingredient_ingredient__rfjvs">½cup (8 tablespoons)/115 grams unsalted butter, very soft</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">2packed tablespoons dark brown sugar</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">1heaping tablespoon gochujang</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">1cup/200 grams granulated sugar</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">1large egg, at room temperature</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">½teaspoon coarse kosher salt or ¾ teaspoon kosher salt (such as Diamond Crystal)</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">¼teaspoon ground cinnamon</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">1teaspoon vanilla extract</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">½teaspoon baking soda</li>
<li class="pantry--ui ingredient_ingredient__rfjvs">1½cups/185 grams all-purpose flour</li>
</ul><div class="ingredients_buttons__DxZKd">
<a class="link_link__7WCQy link_subdued__r23M2 ingredients_linkAppearance___8Rdx" href="https://cooking.nytimes.com/article/ingredient-substitutions">Ingredient Substitution Guide</a>
<div class="popover_popover-container__huJIK">
<div class="popover_popover__Yn69l popover_position-bottom-left__EzAlX popover_has-arrow___w3NR popover_popover--nutritional-information__2Roqz popover_popover-body__aWR9h popover_popover-body--message__fjyF9 c2">
<h5 class="pantry--ui-strong">Nutritional analysis per serving (8 servings)</h5>
<p class="pantry--ui">312 calories; 13 grams fat; 8 grams saturated fat; 0 grams trans fat; 4 grams monounsaturated fat; 1 gram polyunsaturated fat; 47 grams carbohydrates; 1 gram dietary fiber; 29 grams sugars; 4 grams protein; 175 milligrams sodium</p>
<p class="pantry--ui-xs">Note: The information shown is Edamam’s estimate based on available ingredients and preparation. It should not be considered a substitute for a professional nutritionist’s advice.</p>
<a class="link_link__7WCQy link_default__lKxiG ingredients_edamamLink__vWsgN" rel="noreferrer noopener" target="_blank" href="https://www.edamam.com/website/wizard.jsp">Powered by
<div class="ingredients_edamamLogo__pdVqO"><img alt="" width="320" height="78" data-nimg="1" class="c3" srcset="/_next/image?url=%2Fassets%2Fedamam-logo.png&amp;w=320&amp;q=75 1x, /_next/image?url=%2Fassets%2Fedamam-logo.png&amp;w=768&amp;q=75 2x" src="https://cooking.nytimes.com/_next/image?url=%2Fassets%2Fedamam-logo.png&amp;w=768&amp;q=75" /></div>
</a></div>
</div>
</div>
</div>
<div class="recipebody_prep-block__FegRB">
<div class="videocard_textContainer__guX5e"><label class="videocard_videoCard__rrOLM" for="video-card-button">Make the recipe with us</label></div>
<ol class="preparation_stepList___jqWa"><li class="preparation_step__nzZHP">
<div class="pantry--ui-lg-strong preparation_stepNumber__qWIz4">Step 1</div>
<div class="preparation_stepContent__CFrQM">
<p class="pantry--body-long">In a small bowl, stir together 1 tablespoon butter, the brown sugar and gochujang until smooth. Set aside for later, at room temperature.</p>
</div>
</li>
<li class="preparation_step__nzZHP">
<div class="pantry--ui-lg-strong preparation_stepNumber__qWIz4">Step 2</div>
<div class="preparation_stepContent__CFrQM">
<p class="pantry--body-long">In a large bowl, by hand, whisk together the remaining 7 tablespoons butter, the granulated sugar, egg, salt, cinnamon and vanilla until smooth, about 1 minute. Switch to a flexible spatula and stir in the baking soda. Add the flour and gently stir to combine. Place this large bowl in the refrigerator until the dough is less sticky but still soft and pliable, 15 to 20 minutes.</p>
</div>
</li>
<li class="preparation_step__nzZHP">
<div class="pantry--ui-lg-strong preparation_stepNumber__qWIz4">Step 3</div>
<div class="preparation_stepContent__CFrQM">
<p class="pantry--body-long">While the dough is chilling, heat the oven to 350 degrees and line 2 large sheet pans with parchment.</p>
</div>
</li>
<li class="preparation_step__nzZHP">
<div class="pantry--ui-lg-strong preparation_stepNumber__qWIz4">Step 4</div>
<div class="preparation_stepContent__CFrQM">
<p class="pantry--body-long">Remove the dough from the refrigerator. In 3 to 4 separately spaced out blobs, spoon the gochujang mixture over the cookie dough. Moving in long circular strokes, swirl the gochujang mixture into the cookie dough so you have streaks of orange-red rippled throughout the beige. Be sure not to overmix at this stage, as you want wide, distinct strips of gochujang.</p>
</div>
</li>
<li class="preparation_step__nzZHP">
<div class="pantry--ui-lg-strong preparation_stepNumber__qWIz4">Step 5</div>
<div class="preparation_stepContent__CFrQM">
<p class="pantry--body-long">Use an ice cream scoop to plop out ¼-cup rounds spaced at least 3 inches apart on the sheet pans. (You should get 4 to 5 cookies per pan.) Bake until lightly golden at the edges and dry and set in the center, 11 to 13 minutes, rotating the pans halfway through. Let cool completely on the sheet pan; the cookies will flatten slightly and continue cooking as they cool. The cookies will keep in an airtight container at room temperature for up to 2 days.</p>
</div>
</li>
</ol></div>
</div><div class="notessection_notesPrintLayout__KvaNY">
<p class="pantry--ui-strong">Private Notes</p>
<div class="pantry--body-long notesemptystate_emptyState__MpxEg">Leave a Private Comment on this recipe and see it here.</div>
</div>]]></description>
      <link>https://cooking.nytimes.com/recipes/1023675-gochujang-caramel-cookies</link>
      <guid>https://cooking.nytimes.com/recipes/1023675-gochujang-caramel-cookies</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Buckle Up for Bumpier Skies | The New Yorker]]></title>
      <description><![CDATA[<div class="body__inner-container"><figure data-testid="cne-audio-embed-figure" class="CneAudioEmbedFigure-cwqusU dGMPjV"><div data-testid="cne-audio-embed-container"></div></figure><p class="has-dropcap has-dropcap__lead-standard-heading paywall">The cabin crew had just served breakfast when Dzafran Azmir felt the first tremor. He and the other two hundred and ten passengers on Singapore Airlines Flight SQ321 had been in the air for more than ten hours. Their flight had taken off the night before from the United Kingdom, where Azmir was studying audio engineering at the University of Plymouth, and had flown across Central Europe, the Black Sea, Turkmenistan, and Pakistan. They were thirty-seven thousand feet above the Irrawaddy River, in Myanmar—three hours from their scheduled landing in Singapore—when the turbulence started. For a moment, the plane quivered around them like a greyhound straining on a leash. Then it lifted its nose and leaped forward on an updraft. Eleven seconds later—at 7:49:32 <em class="small">A.M.</em> on May 21, 2024, according to the flight’s data recorder—the pilots switched on the “Fasten Seat Belt” sign and told the flight attendants to secure the cabin. They were in for some rough weather.</p><p class="paywall">Late spring is the start of the wet monsoon season in Myanmar, when heavy rains and squalling winds sweep in from the Bay of Bengal. If the pilots had been equipped with better radar or forecasting software, they might have known to avoid the towering storm clouds welling up beneath them. But, aside from a few white cloud tops, the sky outside the plane was clear and bright. Those first tremors were their only warning.</p><div><div class="ConsumerMarketingUnitThemedWrapper-kjbXjp gnOkbl consumer-marketing-unit consumer-marketing-unit--article-mid-content" role="presentation" aria-hidden="true"></div><p class="paywall">In 2002, a team of researchers from <a href="https://www.newyorker.com/tag/nasa"><em class="small">NASA</em></a>, the F.A.A., and six commercial airlines ran a series of experiments in Oklahoma City, in a decommissioned <a href="https://www.newyorker.com/news/dispatch/the-world-the-747-didnt-predict">Boeing 747</a>. They wanted to see how quickly a commercial jet could be secured in case of turbulence. They recruited a group of volunteer passengers, gave them all fake boarding passes and luggage, and had three of them carry around life-size baby dolls. Some of the volunteers were told to stay in their seats and act as if they were sleeping, reading, or working on a laptop. Others were told to stand in the aisles or sit in the lavatories. A crew of experienced flight attendants, drawn from the airlines participating in the study, made their way up and down the plane, serving fake food.</p><p class="paywall">The research team ran nineteen drills in three days. Some began with a mild warning over the intercom: “Ladies and gentlemen, this is your captain speaking. We will be encountering a line of thunderstorms in about ten minutes.” The rest began more urgently: “All passengers and flight attendants, please be seated immediately.” The more emphatic announcement prompted a quicker reaction. Still, at best, only two-thirds of the occupants were buckled up after seventy seconds. On average, the passengers needed a minute and a half to take their seats; the flight attendants, who had to stow their gear first, needed at least four minutes. Fully a third of the occupants were still out of their seats after seventy seconds.</p></div><div class="body__inner-container"><p class="paywall">To the people on Flight SQ321, that would have seemed an eternity. Eight seconds after the captain’s warning, the plane plummeted. Within five seconds, it had dropped a hundred and seventy-eight feet—about the height of a nineteen-story building. There was no time to react, Azmir later told reporters. “Whoever wasn’t buckled down, they were just launched into the air within the cabin,” he said. Azmir had a window seat near the back. When a plane hits turbulence, it tends to seesaw from front to back, so the first and last rows rise and fall the most. “I saw people from across the aisle just going completely horizontal, hitting the ceiling,” Azmir said. “People getting massive gashes in the head.” Some passengers were vaulted up so violently that they dented the luggage bins, or thrust their heads through the panels where the oxygen masks were stored. Those who were standing were sent somersaulting down the aisles; those sitting in the lavatories smashed into the ceiling. It was “sheer terror,” one passenger later said. Then, just as abruptly, the plane lurched up, slamming everyone back to the ground. In just four seconds, the gravitational force on their bodies changed from negative 1.5 g’s to positive 1.5 g’s, Singapore’s Ministry of Transport later noted. It was as if their bodies went from being helium balloons to being sandbags.</p><p class="paywall">“I arrived back in the airport and I couldn’t stop vomiting,” another passenger said, after the plane had made an emergency landing in Bangkok. “I couldn’t walk.” A hundred and four passengers had to be treated for injuries. More than forty of them were kept for longer stays at the hospital; six had skull and brain injuries, including a two-year-old boy. Of the seventeen passengers who needed surgery, nine had spinal injuries, including an Australian woman named Kerry Jordan, who was left paralyzed. A year later, she still couldn’t brush her teeth or use a phone.</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">Turbulence is the ghost in the attic of air travel—the bump and shake and rattling groan that we do our best to ignore, though it sounds like it wants to kill us. Most of the time, it hovers over mountains and in storm clouds, easy enough to avoid. Pilots can see bad weather lurking in the distance hours before takeoff, glowing like a wraith on their digital maps. If it moves, the plane’s radar can still spot it eighty miles ahead or more. But the updraft that struck Flight SQ321 was of a more sinister sort. Although it came from the storm clouds below, there was seemingly no rain in it for radar beams to reflect against. It was like an invisible speed bump in the sky.</p></div><div class="body__inner-container"><p class="paywall">In 1966, a Boeing 707 operated by the British Overseas Airways Corporation took off from Tokyo en route to Hong Kong. It was a sunny, cloudless afternoon, but as the plane approached Mt. Fuji a violent wind struck it from the northwest. The gust tore the vertical fin from the tail and hurled it into the left horizontal stabilizer, which broke off in turn. As the plane twisted upward, the air pressure wrenched off another tail fin. All four engines were ripped from the wings, sending the plane spinning toward the mountain’s flank. The fuel tanks ruptured, and the entire tail section fell off, along with the right wing. By the time the plane crashed, in a forest at thirty-five hundred feet, its fuselage had broken in two and a trail of debris ten miles long stretched behind it.</p><p class="paywall">The Mt. Fuji crash was one of a series of plane accidents in Japan that year. One commercial jet careened into a seawall while landing in heavy fog; another plunged into Tokyo Bay for unknown reasons; yet another, into Japan’s Seto Inland Sea, also for unknown reasons. It was one of the deadliest years in commercial-aviation history—three hundred and seventy-one passengers and crew were killed in those incidents alone—and it changed the way that airplanes were built.</p><p class="paywall">When new employees come to work at the Boeing production facility in Everett, Washington, one of their first stops is often an exhibition at the company’s Safety Experience Center. It opens on a sombre note: a memorial for famous air disasters, including the successive crashes of two <a href="https://www.newyorker.com/magazine/2019/11/18/the-case-against-boeing">737 <em class="small">MAXs</em></a>, in 2018 and 2019, in the Java Sea and Ethiopia. Then, gradually, the tone grows more hopeful. At Boeing, as throughout the aviation industry, disasters led to innovations. Oxygen masks and electronic anti-skid brakes were introduced in the nineteen-sixties, along with bird cannons at airports, to shoo off Canada geese and fellow-fliers. Overhead bins got latched doors that same decade, to keep luggage from toppling onto passengers’ heads. Satellite communication came along in the seventies; automated flight-management systems, capable of plotting a plane’s course, speed, and altitude, in the eighties. Radar systems got more accurate; planes grew stronger, sleeker, and more flexible. Pilots got better at skirting turbulence—or, if they couldn’t, at slowing down and “riding the bumps.”</p><figure class="AssetEmbedWrapper-iJvQnD cOWUYC asset-embed"><div class="AssetEmbedAssetContainer-fnduJP iaVSwI asset-embed__asset-container"></div></figure><p class="paywall">“When people get hurt around our products, we need to take every ounce of education from it that we can,” Jacob Zeiger, a senior air-safety investigator at Boeing, told me, when I visited the Boeing facility this past December. “These technical findings are sacred.” Within hours of any major incident involving a Boeing plane, Zeiger and his team are notified, and they may spend a week to ten days studying the damage and interviewing the crew, piecing together what went wrong. In 2008, for instance, the engines on a 777 stopped responding, and it crash-landed short of a runway in London, shearing off its landing gear. Afterward, a team of investigators re-created the plane’s fuel system in a Boeing lab. A small heat-exchange unit, they found, had accumulated ice during the flight. Every 777 has since been retrofitted with a new version of the unit. Thanks to decades of such refinements, today’s jets may be the world’s most reliable machines. Flying in them is less likely to kill you than walking on staircases.</p><p class="paywall">It’s the sky that’s grown more unreliable. Fierce storms and erratic winds are increasingly common with climate change. But the rise in clear-air turbulence, often far from storms and undetectable by radar, is especially alarming. Since 1979, clear-air turbulence has increased by as much as fifty-five per cent over the North Atlantic and forty-one per cent over the United States. If temperatures continue to rise unabated, it could more than double by the middle of the century. Death by turbulence is still vanishingly rare, but Flight SQ321 did have one fatality. Geoffrey Kitchen, a retired insurance salesman from Bristol, England, on holiday with his wife of fifty years, died before the plane landed. Its sudden plunge had come as such a shock, it seems, that it gave him a heart attack.</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">I’m not an especially fearful flier, but I dread turbulence all the same. I avoid seats in the back of a plane, check radar maps before a flight, and keep my seat belt buckled even when the light is off. I remember a conversation I once had with the forensic anthropologist Clyde Snow, who spent years investigating plane crashes for the F.A.A. In his experience, he said, when a crash did have survivors, a disproportionate number of them were men: they were the first to shove and claw their way to the exits. As he put it in 1970, in a study that included two plane crashes in which the passengers had to flee from burning cabins, “It appears that younger males were definitely favored . . . where speed, strength, and agility would be expected to play a dominant role.” In those two crashes, even the old men survived at a higher rate than the adult women and children.</p></div><div class="body__inner-container"><p class="paywall">That image has always stuck with me, both as a sobering comment on my sex and as a grisly worst-case scenario. So it was strange, this fall, to be looking for a bumpy ride. Some sixteen million flights crisscross the United States each year. Of those, roughly one in every two hundred and fifty gets hit by moderate-or-greater turbulence—strong enough to make passengers feel “a definite strain against their seat belts,” as the National Weather Service describes it. One in every three thousand flights encounters severe turbulence: “The airplane may momentarily be out of control. Occupants of the airplane will be forced violently against their seat belts.” By that scale, the worst turbulence I’ve felt could only qualify as light: “slight erratic changes in altitude.” To definitely experience more, I would have to fly in a very small aircraft.</p><p class="paywall">The most turbulent flight routes in North America are over Colorado, where the prevailing winds from the west barrel into the high peaks of the Rockies and tumble onto the High Plains below. One morning this fall, on a stubbly brown field in Boulder, a glider pilot named Dan Swenson stared up at the sky and shook his head. A vast, lens-shaped cloud hung above us like an alien mother ship. It stretched from the foothills of the Front Range, in the west, to the Laramie Mountains, in the north, its pale upper reaches darkening to a gunmetal gray along the bottom. “So, what’s with this?” he said. He glanced over at Jordon Griffler, the scraggly young pilot who would tow Swenson’s glider into the sky with his single-prop plane. Griffler shrugged and took a bite of a bagel. “You can ride that all the way to Wyoming,” he said. Swenson shook his head again: “Holy cow!”</p><p class="paywall">Swenson is seventy-four, with a silver mustache and a well-upholstered body, and has been piloting gliders since he was thirty. Today’s flight would be his eight-thousand-eight-hundred-and-sixty-third, but that hardly made it predictable. “Forecasts are forecasts,” he said. “Most of the time, they don’t even get them right the day after.” Our previous day’s flight had been cancelled because of dangerous winds. Did today’s conditions worry him? “The answer to that is no,” he said. “As a soaring pilot, this is the kind of stuff that can get you really excited. Just think about water. If we’re out on the ocean in a sailboat, and there are these little waves and everything’s nice, and all of a sudden there’s this great big wave coming through, the experienced captain will go, ‘Rogue wave!’ It’s just part of the deal. ‘That scared the shit out of me!’ Part of the deal.”</p><p class="paywall">This was less than reassuring. As was the sight of Swenson’s glider—a dinged-up, silver-and-orange craft that looked like some kids had built it in their junior-high rocketry club. Nevertheless, we were soon in the air. Griffler’s plane towed us high above the foothills on a thin gray rope. There was a bang, the rope fell away, and we were floating free at ten thousand feet.</p></div><div class="body__inner-container"><p class="paywall">For a moment, I forgot myself in the sheer, giddy wonder of it, lofting like a blown leaf above forests, lakes, and an old railway winding into the mountains below. Then the first wave of turbulence hit. It felt like skidding on black ice—the sudden, sickening drop, the bewildering weightlessness—only I had no brake, no steering wheel, no hope of bailing out. The closest thing to grab was a large copper-colored knob on the dashboard, labelled “<em class="small">RELEASE</em>.” But I’d been told not to do that under any circumstance, unless I wanted a very short flight. (I later learned that it was meant for the towing cable.) “We’re in that rotary stuff now!” Swenson shouted from the seat behind mine. When strong winds blow over a mountain range, they’re bent into huge, oscillating waves up high, while the air below spins down the slopes in ragged gusts, known as rotor clouds. It felt like driving over a row of logs. “I once had a passenger who threw up five times before we even released the rope!” Swenson said.</p><p class="paywall">Swenson’s glider was an exquisite instrument for detecting turbulence. A jumbo jet can weigh upward of half a million pounds and fly more than five hundred miles an hour. It charges through the air like an ocean liner, barely registering most winds. This glider wasn’t much heavier than a Harley and it was moving about as fast—fifty to seventy miles an hour. It felt every bump. Small aircraft account for many of the injuries caused by turbulence and, essentially, all of the deaths—about forty a year. They fly at the mercy of the wind.</p><p class="paywall">“You doing O.K.?” Swenson shouted, after a while. “The more you’re talking, the better I know you’re doing.” I tried to say I was fine, but it came out funny—a high, choked-off sound. I waited a moment, then covered for it by asking what he did for a living before he retired. He laughed. “I worked for Northwestern Mutual in Boulder,” he said. “I sold life insurance.”</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">Far below us, at the base of the Front Range, I could see a group of tall red towers rising from a meadow of yellow bunchgrass. They looked ancient from this distance—like the cliff-dwellings of Mesa Verde—but also vaguely futuristic. <a href="https://www.newyorker.com/magazine/1993/10/25/woody-allen-the-outsider">Woody Allen</a>, in his sci-fi spoof, “Sleeper,” used them as the setting for a sinister cloning institute. In fact, they housed the National Center for Atmospheric Research, or <em class="small">NCAR</em>, one of a group of federally funded centers that were created, after the Second World War, to apply the most advanced research to the most urgent practical problems. It was the Los Alamos of turbulence. When I went there later that morning, I half expected the buildings to be dark. The government was shut down, and the National Science Foundation was facing huge budget cuts. But <em class="small">NCAR</em> was still open, for now.</p></div><div class="body__inner-container"><p class="paywall">Inside the main building, a large glass globe was perched on a steel stand. It was filled with an iridescent blue liquid that moved in ever more complicated patterns when I spun the globe, like clouds above a rotating planet. It was meant to show the chaotic nature of the atmosphere, but it was a drastic oversimplification. On Earth, air heats and rises along the equator as the planet turns, then cools and sinks when it reaches the poles. Mountains and valleys shape the paths of the wind; volcanoes scorch the air and shade it with their ash; ocean currents absorb heat and then evaporate into the sky, churning the air with their vapors. And, everywhere, warm and cold fronts rub against each other, setting off still more swirling changes. To truly capture that complexity, I would have had to shake the ball like a snow globe.</p><p class="paywall">“Turbulence is one of the great unsolved problems in classical physics,” Larry Cornman, a senior researcher at <em class="small">NCAR</em>, told me, when we spoke in his office. “You have to predict where these things will happen and when, but the equations are inherently nonlinear.” Cornman is sixty-eight, with brown hair, streaked with gray, that hangs below his shoulders. He was dressed in a T-shirt and a tracksuit jacket, and spoke with an offbeat affability—a holdover from Boulder’s hippie days. Before earning degrees in math and physics from the University of California, Santa Cruz, Cornman lived in a Buddhist commune in Northern California for three years. When he moved to Boulder, in 1983, he took a job at <em class="small">NCAR</em> as a part-time computer programmer, and never left. He has since earned eight patents and devised some of the most widely used systems for detecting turbulence.</p><p class="paywall">Cornman arrived in Colorado just as the airlines were confronting a series of mysterious crashes. On June 24, 1975, an Eastern Airlines plane was blown to the ground half a mile short of its runway in New York. It collided with some approach light towers and burst into flames, scattering its pieces across Rockaway Boulevard. Seven years later, in New Orleans, a Pan Am flight was forced down by the wind just after takeoff. It plowed into an adjacent neighborhood, killing eight people on the ground and all its passengers. In the U.S. alone, similar wind-shear accidents killed more than four hundred people between 1973 and 1985.</p><p class="paywall">“People were dying and we didn’t know why,” Cornman told me. “We didn’t understand the physics of why the planes were crashing.” The deadly gusts were thought to be blowing in from the ocean or from thunderstorms outside the airports. But the danger turned out to be right above them. In the late seventies, researchers at <em class="small">NCAR</em> and the University of Chicago discovered that the crashes were caused by microbursts—sudden, violent downdrafts. In a microburst, a storm cloud dumps cool air and rain straight down, like water from a broken awning. The air spreads horizontally after it lands, so the pilot thinks he’s flying into a headwind at first. He lifts the plane’s nose slightly and decreases the engines’ thrust. Then the downdraft hits, followed by a vicious tailwind, sending the aircraft to the ground.</p></div><div class="body__inner-container"><p class="paywall">The <em class="small">NCAR</em> team spent the next ten years working on the problem with researchers at airlines, universities, the F.A.A., <em class="small">NASA</em>, and <em class="small">NOAA</em>—the National Oceanic and Atmospheric Administration. “It was a national imperative,” Cornman said. Luckily, the beginnings of a solution were already in place. The team at <em class="small">NCAR</em> had used sophisticated new Doppler radar systems to detect microbursts. When those were added to the wind detectors already installed at many airports, and the two systems were integrated with software that Cornman developed, microbursts could be detected as they were happening. “A problem where hundreds of people were dying suddenly stopped,” Cornman said. The last time a commercial flight was downed by a microburst in the U.S. was in 1994.</p><p class="paywall">Turbulence is rarely that simple. It’s too scattered, too mercurial, too easily triggered by weather patterns that trigger other patterns in an endless cascade. “It’s not just one thing that’s going on,” Bob Sharman, an atmospheric scientist at <em class="small">NCAR</em>, told me. “It’s not just atmospheric convection. It’s not just wind flowing over mountains. It’s everything going on all the time and interacting.” Sharman is one of the country’s preëminent authorities on turbulence prediction. The computer models that he has built can predict where rough air is most likely to arise. “The problem is,” he said, “when we go to meetings with the airline industry and suggest a probabilistic approach, a pilot will stand up and say, ‘No! I want you to tell me if there will be turbulence at this place, at this time.’ ” Sharman threw up his hands. “Nobody knows that. I understand that, in theory, you would want that. But, in practice, that is just not possible.”</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">Early in October, I took a red-eye flight from New York to Santiago, Chile. I’d been reading a website called Turbli, run by a turbulence-obsessed engineer in Stockholm named Ignacio Gallego-Marcos, who has a Ph.D. in fluid dynamics. Gallego-Marcos had gone through a year’s worth of forecasts from <em class="small">NOAA</em> and the Met Office—the U.K.’s national weather service—and combined them with flight-tracking data from around the globe. In 2025, he concluded, three of the five bumpiest flight routes in the world flew into Santiago.</p><p class="paywall">Chile is like a giant laboratory for unstable winds. When the jet stream crosses the Pacific, it slams into the Andes at an almost perfect right angle. On the Chilean side, the climate is sunny, stable, and dry. On the Argentinean side, fierce winds rise and fall above the peaks in mountain waves, tossing up rows of thin white clouds like foamy crests. In winter, the air below the peaks can plunge into the Uco Valley, in a stifling zonda wind. The sudden compression generates terrific heat, sending temperatures above a hundred degrees in Mendoza, Argentina. “It is very psychologically difficult,” Roberto Rondanelli, an atmospheric scientist at the University of Chile, told me, when we met in Santiago. “People get crazy in Mendoza.”</p></div><div class="body__inner-container"><p class="paywall">Things get even worse to the northeast. As the dry valleys of Argentina give way to subtropical rain forest, the humidity rises in tremendous thunderheads and rushes back down in torrential rains as it cools. The convection drives huge, lashing winds through the atmosphere, with violent updrafts and downdrafts. “We don’t get this in Chile,” Rondanelli said. “As a meteorologist, I really resent that. We are the boring part. In Argentina, they have all kinds of crazy weather. Hail that is almost baseball-size! The biggest storms in the world—a thousand kilometres wide! I would love to cross one of those storms.” He sighed. “I have three kids and two stepkids, so I may not do this. But I would love to feel how it is to be inside them—without dying, hopefully.”</p><figure class="AssetEmbedWrapper-iJvQnD cOWUYC asset-embed"><div class="AssetEmbedAssetContainer-fnduJP iaVSwI asset-embed__asset-container"></div></figure><p class="paywall">A modern jet has an array of sensors to help it contend with bad weather. Magnetometers track the plane’s direction; gyroscopes help calculate its pitch and roll; accelerometers detect its changes in speed; Doppler radar measures the distance to the storm and how quickly it’s moving. In the early nineties, Larry Cornman developed a program that could sift through some of that sensor data to measure the air’s turbulence in real time. Atmospheric scientists call this the “eddy dissipation rate,” or E.D.R. It’s usually scored between 0 and 1—calm to severe.</p><p class="paywall">The flight from Mendoza to Santiago is the bumpiest in the world by that measure. It has an average E.D.R. of .23. That’s nearly a third higher than the most turbulent routes in North America—from Denver to Jackson Hole and from Albuquerque to Denver—but still far from severe. On a Boeing 737, Cornman told me, an E.D.R. of .23 would register as moderate turbulence—“uncomfortable, especially for long periods, but people won’t hit the ceiling.” Then again, averages can be deceptive. A roller coaster might average only fifteen miles an hour if you include the slow climb up the hill. But that first drop is all you remember.</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">“I can assure you that the scariest flights of my life were crossing the Andes,” a Chilean pilot told me, when I flew from Santiago to Mendoza. He’d been flying over the mountains for more than fifteen years, he said, sometimes in a four-person plane. The high peaks present a Scylla and Charybdis problem in winter, when the jet stream intensifies and storms roll in from the Pacific. Fly high and get tossed around by mountain waves. Fly low and get driven toward the rocks by the zonda wind. “It can throw down a small airplane,” he said.</p></div><div class="body__inner-container"><p class="paywall">Sitting on the plane in Santiago listening to the safety instructions, I imagined how they might sound if they were more like the stories and flight-accident reports I’d been reading: “Should a passenger hit the ceiling twice, do a flip in the air, and land on his stomach . . . Should a service cart topple onto a flight attendant and fracture her ankles . . . Should people start screaming and calling to Jesus . . .” In the U.S., turbulence causes more than a third of all accidents on commercial flights, the National Transportation Safety Board found. Those accidents tend to hurt people in predictable ways. Passengers usually get injured near the back of the plane, for instance, often as they are walking to the lavatory, sitting inside it, or waiting in line. But the total number of injuries is hard to determine. One major airline estimated that it receives two hundred turbulence-related injury claims a year, but the N.T.S.B. doesn’t keep track of “minor injuries”—including those which require a hospital stay of less than forty-eight hours. “These things happen all the time, but because they don’t cause death or serious injury they’re swept under the rug,” an N.T.S.B. senior meteorologist and investigator told me. “We only have about a hundred aviation investigators for fourteen hundred accidents a year.”</p><p class="paywall">If there’s one takeaway from the N.T.S.B. statistics, it’s this: flight attendants are in a hazardous business. When planes hit turbulence, the pilots and passengers are usually in their seats. The flight attendants are often still on their feet. They get nearly eighty per cent of the serious injuries caused by turbulence, and, for every one of those injuries, a 2001 study found, another seventy flight attendants get minor injuries. Nearly a third of the time, they have no idea the turbulence is coming.</p><p class="paywall">“It was relatively calm and the three of us were working in the aft galley,” a flight attendant recalled in an N.T.S.B. crew statement last March, about a flight over the Philippines. “A young little boy entered the galley asking for sandwich snacks. Suddenly, unexpectedly, clear-air turbulence struck. . . . It all happened so fast. I remember flying up and then dropping down hard, hitting the side of one of the carts and then being thrown backwards, hitting hard flat onto the galley floor. My head and back slammed onto the floor and so did the little boy right beside me. His screams of fright and agony when he landed hard on his back still haunt me.”</p><p class="paywall">My flights across the Andes, as it turned out, were among the calmest, most serenely beautiful of my life. On the return trip to Santiago, the sun was setting, and the high peaks floated by soundlessly below, lit amber and violet like corals beneath a glass-bottomed boat. “There are no words to describe it,” a flight attendant from Santiago told me later. “Where else do they have mountains like these?” Still, she said, on a flight across the Andes a year earlier she was shaken up so badly that she couldn’t fly over them again for a while. “I was scared for three months,” she said. Another flight attendant insisted that she wasn’t afraid of turbulence at all. “I’m super used to it,” she said, then added, “But we should not lose the fear of turbulence. If you get too much used to it, you can make mistakes. You can be, like, ‘No, it’s nothing,’ and then <em>paff!</em> ”</p></div><div class="body__inner-container"><p class="has-dropcap has-dropcap__lead-standard-heading paywall">Thirty years ago, atmospheric scientists began to notice a worrisome trend. They knew that turbulence from storms increases in summer, when hotter and more humid air rises to form thunderheads. And they knew that clear-air turbulence increases in winter, when the temperature drops dramatically at the poles but not in the tropics. That temperature difference drives the jet stream, which creates turbulent eddies and wind shear as it rushes through slower bodies of air. But, on top of these seasonal swings, there seemed to be an over-all trend as well: Earth’s atmosphere was getting rougher.</p><p class="paywall">This made intuitive sense. Temperatures had been rising across the globe for nearly a century. The more heat and energy there is in the atmosphere, the more turbulent it ought to be. But the climate tends to frustrate expectations. If temperatures at the poles rise more than temperatures at the tropics, for instance, the difference between them will decrease, and the jet stream could slow down. Nevertheless, on average, turbulence seemed to be rising everywhere. The surprise was how much. Between 1958 and 2001, the weather data suggested, clear-air turbulence increased between forty and ninety per cent over Europe and North America. The British atmospheric scientist Paul Williams found similar increases when he looked at data from satellites, weather balloons, and aircraft from 1979 to 2020. If carbon-dioxide emissions continue apace, Williams estimates, moderate or greater clear-air turbulence could rise by as much as a hundred and seventy per cent on flight routes over the North Atlantic by the middle of the century. Turbulence from storms and other sources could also nearly double, a study co-authored by Bob Sharman found.</p><p class="paywall">How much turbulence can an airplane bear? Every year, the question is asked and answered by a group of Air Force and <em class="small">NOAA</em> pilots and researchers known as the hurricane hunters. The initiative began, unofficially, in 1943, when Lieutenant Colonel Joseph Duckworth flew into the eye of a hurricane near Galveston, Texas. Duckworth made his flight on a dare, but the programs have since taken on a more serious role: to report on hurricanes as they develop and to study their inner mechanics. Last year, Joshua Wadler, a hurricane hunter and a meteorologist at Embry-Riddle Aeronautical University, in Florida, went through the turbulence data from every <em class="small">NOAA</em> hurricane flight since 2004, and two infamous ones from the nineteen-eighties. He measured how much each flight was thrown around along six axes of motion: roll, pitch, yaw, surge, sway, and heave. (The words alone can induce vertigo.) Then he made a list of the bumpiest flights ever recorded.</p></div><div class="body__inner-container"><p class="paywall">Wadler’s own worst flight was through <a href="https://www.newyorker.com/news/daily-comment/hurricane-ian-is-a-storm-that-we-knew-would-occur">Hurricane Ian</a>, in 2022—a trip famous for its furious lurches from side to side. But that flight came in second on his list. The bumpiest of all was through Hurricane Hugo, east of Barbados, in 1989. “It was like riding a roller coaster inside a car wash,” Frank Marks, a <em class="small">NOAA</em> meteorologist who has flown through more than a hundred hurricanes, told me recently. “Within less than a minute and a half, the wind increased to a hundred and seventy miles an hour. And then, just as we’re breaking into the eye, starting to see a little clearing ahead, a little sunlight, someone says, ‘There’s a flame coming out of engine three!’ And we think, Oh, crap.” Their plane, a Lockheed P-3 Orion, nicknamed Kermit, lost power in engine three and fell more than six hundred feet, nearly into the Atlantic. It pulled out of the dive and climbed back into the eye of the storm. Then it circled there for about an hour before an Air Force plane escorted it through a soft spot in the eye wall.</p><p class="paywall">Kermit and its sister plane—another P-3 Orion, nicknamed Miss Piggy—have flown into hundreds of hurricanes since 1976 and never lost a passenger. The Air Force, in that same period, has flown thousands of hurricane flights in its Lockheed WC-130s, also without a single fatality. Both sets of planes were designed for the military: the P-3 is like a flying tank, Marks told me; the WC-130 is more like a flying barn. Commercial jets are built for lighter duty, and they try to steer clear of hurricanes. But how will they fare in a windier world?</p><p class="paywall">“I talk to the airlines, and they realize there is a looming threat,” Paul Williams told me. “But it’s quite distant for them. They see it as decades in the future. The people really taking notice are the designers. The airplanes they’re designing now will still be flying in 2050, so they can’t wait. And here is a bit of a shocking thing: the design and certification standards for air worthiness are based on turbulence measurements from the nineteen-sixties. It’s reasonable to ask, Are those standards still fit for the purpose? Will they still be fit for the purpose in 2050?”</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">When I visited the Boeing facility in December, the company was going through a rough patch. The two 737 <em class="small">MAX</em>s that crashed in 2018 and 2019, killing all their occupants, were brought down by the same faulty sensor: it kept telling the flight-control software to tilt the plane’s nose down. After the second incident, the F.A.A. grounded the entire 737 <em class="small">MAX</em> fleet for twenty months. Then, in 2024, another of the planes ran into trouble. It was climbing to sixteen thousand feet over Portland, Oregon, when one of its side panels blew off, leaving a gaping hole in the plane’s left flank. The cabin pressure dropped so quickly that a fifteen-year-old boy had his shirt ripped off his back. It was later found that the panel was missing four bolts that should have kept it in place.</p></div><div class="body__inner-container"><p class="paywall">“The past five to seven years have been very hard on us personally,” Darrel Larson, a vice-president of operations, told me. Larson, who grew up on a farm in North Dakota, has a rangy frame and a folksy manner. We were standing on the floor of the building where the 777 is constructed—the largest factory in the world by volume. It’s a vast, open hangar, two-thirds of a mile long and a third of a mile wide, subdivided by rows of glass-walled offices. A system of tunnels runs beneath it, and a network of rails above, hung with gantry cranes that can lug an eight-ton engine across the floor. The factory runs around the clock, yet it was eerily quiet. The planes are mostly assembled from modules made at other sites nearby, and pieced together in a strictly orchestrated sequence. Shrink-wrapped airplane lavatories were clustered along the perimeter, next to carts full of bins with numbered parts. It was the world’s most sophisticated Lego set.</p><p class="paywall">Critics have blamed outsourcing for the company’s recent lapses: some twelve hundred suppliers design and manufacture parts for Boeing planes. “There were a number of issues that we had,” Larson said. “But we’re coming out of that. We can’t build airplanes fast enough.” He walked me over to a half-finished 777 that was about to have its wings attached. “I remember my very first fuselage join,” he said. “The mechanics drilled about eight hundred holes, then started inspecting the skin around them. I thought, This is going to take forever!” The wings have to be mated to the body with gaps of five- to ten-thousandths of an inch. Then they’re bolted on with just enough torque to flex and hold fast, even in the most severe turbulence. In Boeing’s stress tests, they can bend almost forty-five degrees and snap back, and withstand years of flexing without structural fatigue. “It’s not a piece of farm equipment,” Larson said. “It’s a life-support system. At thirty-five thousand feet, you can’t pull over.”</p><p class="paywall">When disaster strikes on a flight these days, it’s almost never the way we fear. The wings won’t rip off in a gale. The plane won’t get thrown into a mountain. In the seven decades since the first paying passengers flew on a commercial jet airliner—from London to Johannesburg in 1952—the number of commercial flights has increased exponentially, while the risk of dying on one has grown incredibly small. “It works out to a probability of fatal injury of one in forty-six million flights on U.S. and E.U. airplanes,” Jacob Zeiger, the air-safety investigator at Boeing, told me. When an accident does happen, it’s usually because of human error or a ground collision or some combination of factors, including the simple act of walking around on a bumpy flight.</p><p class="paywall">Airplane designers have done their best to minimize the pain. Since the nineteen-thirties, cabins have evolved from wicker chairs in bare metal tubes to mood-lit cocoons full of curved surfaces. The air has been pressurized so that pilots can fly up to smoother skies. The service carts have been lightened with composites and braced with built-in brakes and stay-closed drawers. Should the plane suddenly drop, the passenger seats can bear a force of sixteen g’s; the jump seats have harnesses to hold down the crew. Should a fire break out, the walls, seat backs, and tray tables are made with self-extinguishing polymers that won’t give off toxic fumes. Floor lights will guide the passengers down darkened aisles, to evacuation slides that inflate and unfurl to the land or water below.</p></div><div class="body__inner-container"><p class="paywall">Still, for all the clever innovations that have made cabins safer, the economics of flight have also potentially made them more dangerous. Planes once furnished with plush recliners and wide-open aisles are now packed with more passengers each year. Those in first class lounge in lie-flat seats with built-in air bags in their seat belts, while those in economy sit shoulder to shoulder and knee to seat back, hoping they won’t crack heads in a storm. In 2021, the F.A.A. published a study on emergency evacuations which concluded that current cabin-seating requirements “can accommodate and not impede egress for 99% of the American population.” But last year a review panel from the National Academies of Sciences, Engineering, and Medicine found that the study was flawed. The F.A.A. trials had included only volunteer passengers with no physical limitations, and none of them was over sixty years old.</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">“It’s a low-margin industry, so it’s always a cost-benefit analysis,” Larry Cornman told me, in Boulder. “But year in and year out, people are getting hurt.” The best way to prevent injuries, Cornman believes, is to avoid turbulence altogether. Air-traffic control will warn pilots of any storms on their weather maps or radar systems. But for clear-air turbulence pilots still rely on reports from other pilots who have already passed through it—an unsatisfactory arrangement for both parties. “A pilot is an analog, qualitative sensor,” Cornman said. “They get bounced around and say, ‘It’s moderate turbulence.’ Well, what does that mean?” A bone-rattling drop on a small plane might feel like a bump or two on a jumbo jet. Or a pilot might be too busy trying to control the plane to comment on the weather at all. “By the time they make the report, it’s happened way back there,” Cornman said. “So the locations aren’t very accurate, either.”</p><figure class="AssetEmbedWrapper-iJvQnD cOWUYC asset-embed"><div class="AssetEmbedAssetContainer-fnduJP iaVSwI asset-embed__asset-container"></div></figure><p class="paywall">Turbulence doesn’t have to be a matter of word-of-mouth. Commercial jets have the capacity to measure and transmit it automatically—using the software Cornman developed at <em class="small">NCAR</em> in the early nineties—and have it relayed to other pilots. The software is freely available to airlines, but most of them balk at the cost of sending and processing the data, and sharing it with others. “It’s not much, but it adds up,” Sharman told me. “A lot of them are saying, ‘Wait a second, we’re barely making it. We can’t afford another hundred thousand on transmission!’ While the ones that are willing to pay for it say, ‘Why should I share my data with somebody else who doesn’t?” So far, only around two thousand planes have been equipped with the software—about one in four planes in the American fleet.</p><p class="paywall">A few years ago, Cornman found a way around the problem. In the U.S., commercial flights served by air-traffic control—some twenty-seven thousand a day—are required to transmit their position, altitude, and velocity. By tracking those transmissions and the planes’ motions over time, a new program that Cornman developed at <em class="small">NCAR</em> can create a moment-by-moment snapshot of turbulence as it’s happening. The F.A.A. is planning to test the program this year. Together with <em class="small">NCAR</em>’s earlier software, Sharman’s forecasting models, and data from radar arrays on the ground, this system could start to give pilots the advance warning they need. “That is the future for me,” Cornman said. “All these operations get integrated in a seamless network. The pilots don’t have to talk to air-traffic control and say, ‘Should I go up or down?’ They just get a display with a color-coded flight track on it. And they see that it looks better a few thousand feet up.”</p></div><div class="body__inner-container"><p class="paywall">There’s just one hitch: the system still needs guinea pigs. Even the best weather models can’t pinpoint where clear-air turbulence will occur. So the <em class="small">NCAR</em> programs continue to rely on firsthand reports from planes that have already been tossed around. New technologies could change that in coming years. A plane equipped with a lidar sensor—which uses lasers to detect much finer particles than radar can—could pick up on turbulence even in a cloudless sky. But lidar systems are still too bulky and expensive to fit into a plane’s nose cone. And the government and the airline industry have been slow to invest in improving them. For now, the best hope for a flight heading into turbulence might be to program the plane itself to ride the bumps.</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">“This is sort of choose your own adventure,” Ryan Pettit, a technical fellow with Boeing’s flight-controls division, told me. We were sitting in the pilot seats of a multipurpose simulator cab. From the inside, it looked like the flight deck of a 777, complete with banks of gauges, switches, and digital screens, and a view of Mt. Rainier through the windshield. From the outside, it looked like a giant, one-eyed robot: a cabin perched on three mechanical legs more than two stories tall. In months of chasing turbulence, the closest I’d come to it on a commercial flight was in Texas, when a thunderstorm struck my plane just as it was preparing to land in Austin. “Folks, it looks like it’ll be smooth sailing for the first hour and forty-five minutes,” the pilot had warned, as we left New York. “Then it’s all downhill from there.” But this simulator was nothing if not reliable. It was turbulence on demand.</p><p class="paywall">Pettit and his colleague Paul Strefling, sitting in the pilot’s seat between us, are engineers in the business of ride quality. Their job is to program the movable parts on an airplane’s tail and wings—the rudder, elevators, and nearly two dozen ailerons, flaperons, and spoilers—to smooth out its flight automatically when turbulence hits. To get data for the simulator, their team takes full-size Boeing jets on research flights over the Rocky Mountains. They hunt for rough air, then loop through it again and again, like race-car drivers on a test track. They record every flutter and quake using the plane’s sensors, then download them to the simulator’s computers. The flight deck we were in could be swapped with one from a 737 or a 787, and the turbulence reprogrammed for the size and shape of those planes. Then, with the flip of a switch in the control room next door, the cab would start to shake and roll on its piston legs, as if having a seizure.</p><p class="paywall">An airplane caught in turbulence moves both as a whole body and as a flexible structure, Pettit said: “It’s sort of mind-blowing, the number of ways an airplane can bend and twist.” To compensate for all that jouncing and twisting, the flight-control software uses the plane’s sensors to calculate the force and direction of the wind. Then it moves the flaps on the wings and tail to counteract the pressure. “Say the airplane is bending like a yardstick,” Pettit said. “The elevator”—the horizontal flap on the tail—“can move to oppose that. Or the rudder will stop it from moving side to side.” If the plane heaves up, the spoilers can press it back down. If it drops, the wing flaps can lift it up. If it starts to roll, the ailerons can right the ship.</p></div><div class="body__inner-container"><p class="paywall">A voice from the control room broke in to make sure we’d snapped on our five-point harnesses. Then the demonstration began: “Three, two, one, <em>now</em>.” The flight deck lurched, and we began to plunge up and down. It was simulating a moderately turbulent wind recorded over Idaho and Montana. But the control room had segregated the wind’s vertical and lateral forces, so I could feel them in isolation. We were being bounced around by the vertical ones now, and it was kind of fun—like riding a hobbyhorse. The lateral motions came next. They were only half as strong, Pettit told me later, but they felt twice as discomfiting—slow, seasick waves like ocean swells. But the worst, by far, were the motions that were both vertical and lateral. When the control room programmed the flight deck to re-create full turbulence, the steady waves suddenly turned chaotic, off-kilter, completely unpredictable. A jolt or two, an odd pause; a little jerk to the side, and then the bottom fell out.</p><p class="paywall">“The trick in turbulence is that it’s all jumbled together,” Pettit said afterward. “When the airplane is bending in that noodly way, your body is bending, too. It’s designed to carry your weight vertically. But, if you’re on a seat, you might move from side to side at one frequency, and then, at a higher frequency, your head might go one way and your body in the other. It can be harder for motion sickness. And there is a frequency where your eyes begin to rattle and you can’t focus anymore.”</p><p class="paywall">We ran a few more tests in the simulator—I kept telling them to crank it up—but the results were largely the same. After each set of waves, the control room would repeat the test, only with the turbulence-dampening software turned on this time. When the motion was only vertical or lateral, the effect was dramatic: big waves turned into small ones. But when the motions were merged the dampening seemed to hardly make a difference. The over-all movement decreased, Strefling assured me, and the software took the edge off a few bumps. But the sudden jolts and drops were still there, and you still didn’t see them coming.</p><p class="paywall">“It’s something I’ve always struggled to explain,” Strefling said. “Sometimes you have chaotic events with multiple modes that suddenly coalesce, and those things are really hard to dampen and control. It bothers me to my core that I can’t improve them. You know, I’ve been working on this for over a decade. I will never stop working on it. I will work on it forever.”</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">When I flew out of Seattle the next day, the sky was roiled with clouds, threatening rain. The government shutdown had ended, but the atmosphere still seemed suspiciously under-monitored. The National Weather Service had lost some six hundred workers; the F.A.A. was short more than three thousand air-traffic controllers; and there was talk of dismantling <em class="small">NCAR</em> altogether. <a href="https://www.newyorker.com/magazine/2025/10/27/russell-vought-profile-donald-trump">Russell Vought</a>, the director of the White House Office of Management and Budget, had called the research center “one of the largest sources of climate alarmism in the country.”</p></div><div class="body__inner-container"><p class="paywall">Still, when my plane’s turn came, the takeoff was as exhilarating as ever—the low rumble and rising thrum, the smooth detachment and sudden lift, and then the surge through clouds into a piercing blue sky. To fly is to be suspended in disbelief. Hurtling through thin air at subzero temperatures, thirty-five thousand feet above Earth, you have no choice but to trust that the atmosphere won’t kill you. That the giant machine you’ve boarded won’t fall apart. A Boeing 777 is pieced together from more than three million components, many of them essential to keeping it aloft. And the atmosphere has countless more moving parts. As the French aviation pioneer Pierre-Georges Latécoère put it, in 1918, “I’ve redone all the calculations, and they confirm what the experts say: It can’t work. There’s only one thing to do: Make it work.”</p><p class="paywall">Our fear of turbulence is both a natural and a disproportionate response to that improbable feat. Our reactions to it are as chaotic and nonlinear as the winds themselves. “It’s easy to run a simulation for a few seconds and make it a little better,” Pettit said. “But if you’re in flight and you’re getting that moderate turbulence for an hour or two, the anxiety builds up. After a while, I’m, like, Turn this airplane around, I want to go home. I don’t need to go to Hawaii anymore.” ♦</p></div></div>]]></description>
      <link>https://www.newyorker.com/magazine/2026/03/09/buckle-up-for-bumpier-skies</link>
      <guid>https://www.newyorker.com/magazine/2026/03/09/buckle-up-for-bumpier-skies</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[I'm Building Agents That Run While I Sleep]]></title>
      <description><![CDATA[<div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">I've been building agents that write code while I sleep. Tools like Gastown run for hours without me watching. Changes land in branches I haven't read. A few weeks ago I realized I had no reliable way to know if any of it was correct: whether it actually does what I said it should do.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">I care about this. I don't want to push slop, and I had no real answer.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">I've run Claude Code workshops for over 100 engineers in the last six months. Same problem everywhere, just at different scales. Teams using Claude for everyday PRs are merging 40-50 a week instead of 10. Teams are spending a lot more time in code reviews.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">As systems get more autonomous, the problem compounds. At some point you're not reviewing diffs at all, just watching deploys and hoping something doesn't break.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">So the question I kept coming back to: what do you actually trust when you can't review everything?</p></div><div class="dream-post-content-imageBlock _2fealp0 _2fealp1 c27"><picture><source media="(max-width: 360px) and (min-resolution: 2dppx)" srcset="https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,quality=80,format=auto,width=720,onerror=redirect/uploads/asset/file/5d1c9a2d-9892-4e91-9530-dcb9520ba50c/am9xlb.jpg 2x" /><source media="(max-width: 360px)" srcset="https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,quality=80,format=auto,width=360,onerror=redirect/uploads/asset/file/5d1c9a2d-9892-4e91-9530-dcb9520ba50c/am9xlb.jpg 1x" /><source media="(max-width: 430px) and (min-resolution: 2dppx)" srcset="https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,quality=80,format=auto,width=860,onerror=redirect/uploads/asset/file/5d1c9a2d-9892-4e91-9530-dcb9520ba50c/am9xlb.jpg 2x" /><source media="(max-width: 430px)" srcset="https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,quality=80,format=auto,width=430,onerror=redirect/uploads/asset/file/5d1c9a2d-9892-4e91-9530-dcb9520ba50c/am9xlb.jpg 1x" /><img src="https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,quality=80,format=auto,onerror=redirect/uploads/asset/file/5d1c9a2d-9892-4e91-9530-dcb9520ba50c/am9xlb.jpg" alt="" class="_2fealp2 _2fealp5 c26" /></picture></div><p></p><h3 class="hynlcx1 hynlcx4">The obvious answers don't work</h3><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">You could hire more reviewers. But you can't hire fast enough. And making senior engineers read AI-generated code all day isn't worth it.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">When Claude writes tests for code Claude just wrote, it's checking its own work. The tests prove the code does what Claude thought you wanted. Not what you actually wanted. They catch regressions but not the original misunderstanding.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">When you use the same AI for both, you've built a self-congratulation machine.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">This is exactly the problem code review was supposed to solve: a second set of eyes that wasn't the original author. But one AI writing and another AI checking isn't a fresh set of eyes. They come from the same place. They'll miss the same things.</p></div><p></p><h3 class="hynlcx1 hynlcx4">The thing TDD got right</h3><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">Write the test first, write the code second, stop when the test passes. Most teams don't do this because thinking through what the code should do before writing it takes time they don't have.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">AI removes that excuse, because Claude handles the speed. The slow part is now figuring out if the code is right. That's what TDD was built for: write down what correct looks like, then check it.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">TDD asks you to write unit tests, which means thinking about how the code will work before you write it. This is easier. Write down what the feature should do in plain English. The machine figures out how to check it.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">"Users can authenticate with email and password. On wrong credentials they see 'Invalid email or password.' On success they land on /dashboard. The session token expires after 24 hours." You can write that before you open a code editor. The agent builds it. Something else checks it.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1"><em>P.S I write about Claude Code internals every week. Last week I wrote about how</em> Claude Code is a while loop with 23 tools. <em>Subscribe to get the next one!</em></p></div><p><a href="https://www.claudecodecamp.com/subscribe" class="ykh5t1 c28" type="button" target="_blank">Subscribe</a></p><p></p><h3 class="hynlcx1 hynlcx4">What this looks like in practice</h3><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">For frontend changes, we generated acceptance criterias based on the spec file:</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1"># Task<br />Add email/password login.</p><p>## Acceptance Criteria</p><p>### AC-1: Successful login<br />- User at /login with valid credentials gets redirected to /dashboard<br />- Session cookie is set</p><p>### AC-2: Wrong password error<br />- User sees exactly "Invalid email or password"<br />- User stays on /login</p><p>### AC-3: Empty field validation<br />- Submit disabled when either field is empty, or inline error on empty submit</p><p>### AC-4: Rate limiting<br />- After 5 failed attempts, login blocked for 60 seconds<br />- User sees a message with the wait time</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">Each criterion is specific enough that it either passes or fails. Once the agent builds the feature, verification runs Playwright browser agents against each AC, takes screenshots, and produces a report with per-criterion verdicts. If something fails you see exactly which criterion and what the browser saw.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">For backend changes the same pattern works without a browser. You specify observable API behavior (status codes, response headers, error messages) that curl commands can check.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">One thing worth being honest about: this doesn't catch spec misunderstandings. If your spec was wrong to begin with, the checks will pass even when the feature is wrong. What Playwright does catch is integration failures, rendering bugs, and behavior that works in theory but breaks in a real browser. That's a narrower claim than "verified correct," but it's more than a code review was reliably catching anyway.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">The workflow: write acceptance criteria before you prompt, let the agent build against them, run verification, review only the failures. You review failures instead of diffs.</p></div><p></p><h3 class="hynlcx1 hynlcx4">How to build it</h3><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">I started building a Claude Skill (<a href="https://github.com/opslane/verify" target="_blank" rel="" class="_3k8pkd0">github.com/opslane/verify</a>) that runs using <strong>claude -p</strong> (Claude Code's headless mode) plus Playwright MCP. No custom backend, no extra API keys beyond your existing Claude OAuth token. Four stages:</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1"><strong>Pre-flight</strong> is pure bash, no LLM. Is the dev server running? Is the auth session valid? Does a spec file exist? Fail fast before spending any tokens.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1"><strong>The planner</strong> is one Opus call. It reads your spec and the files you changed. It figures out what each check needs and how to run it. It also reads your code to find the right selectors, so it's not guessing at class names.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1"><strong>Browser agents</strong> are one Sonnet call per AC, all running in parallel. Five ACs, five agents, each navigating and screenshotting independently. Sonnet costs 3-4x less than Opus here and works just as well for clicking around.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1"><strong>The judge</strong> is one final Opus call that reads all the evidence and returns a verdict per criterion: pass, fail, or needs-human-review.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">claude -p --model claude-opus-4-6 \<br />"Review this evidence and return a verdict for each AC.<br />Evidence: $(cat .verify/evidence/*/result.json)<br />Return JSON: {verdicts: [{id, passed, reasoning}]}"</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">Install it as a Claude Code plugin:</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">/plugin marketplace add opslane/verify<br />/plugin install opslane-verify@opslane/verify</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">Or clone the repo and adapt it. Each stage is a single <strong>claude -p</strong> call with a clear input and structured output. You can swap models, add stages, or wire it into CI with <strong>--dangerously-skip-permissions</strong>.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">The thing I keep coming back to: you can't trust what an agent produces unless you told it what "done" looks like before it started. Writing acceptance criteria is harder than writing a prompt, because it forces you to think through edge cases before you've seen them. Engineers resist it for the same reason they resisted TDD, because it feels slower at the start.</p></div><div class="j6zgbu0"><p class="dream-post-content-paragraph j6zgbu1">Without them, all you can do is read the output and hope it's right.<br /></p></div>]]></description>
      <link>https://www.claudecodecamp.com/p/i-m-building-agents-that-run-while-i-sleep</link>
      <guid>https://www.claudecodecamp.com/p/i-m-building-agents-that-run-while-i-sleep</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Corpus Christi careens toward water catastrophe]]></title>
      <description><![CDATA[<div class="everlit-disclaimer c21">Audio recording is automated for accessibility. Humans wrote and edited the story. See our <a href="https://www.texastribune.org/about/ethics/#ai-policy">AI policy</a>, and give us <a href="https://airtable.com/appFeleeKVUN0Iytx/pagPG40gbkU0EfjIr/form">feedback</a>.</div><p><em>This story is published in partnership with <a href="https://insideclimatenews.org/">Inside Climate News</a>, a nonprofit, independent news organization that covers climate, energy and the environment. Sign up for the ICN newsletter <a href="https://insideclimatenews.org/newsletter/">here.</a></em></p>
<p>CORPUS CHRISTI — The imminent depletion of water supplies in Corpus Christi threatens to cut off the flow of jet fuel to Texas airports and other oil exports from one of the nation’s largest petroleum ports, triggering potential shockwaves through energy markets in Texas and beyond.</p>
<p>Without significant rainfall, Corpus Christi is headed for a “water emergency” within months and will reach a point next year where city supply can no longer meet demand, according to the city’s website. At that critical point, the city would be unable to deliver water to its customers — a potential catastrophe for Corpus Christi and beyond, experts and people knowledgable about the city’s water system say.</p>
<aside class="scaip scaip-1">
</aside><p>“The impacts are going to be felt tremendously through the state, if not internationally,” said Sean Strawbridge, former CEO of the Port of Corpus Christi Authority, the nation’s top port for crude oil exports, in a 40-minute interview Thursday. “This should be no surprise to anybody. We were talking about this over a decade ago.”</p>
<p>Other current and former officials, alarmed at what they call a lack of preparations, have suggested the potential for an economic crisis involving mass layoffs, disruption of fuel supplies and billions of dollars in emergency spending to avoid an evacuation of the city.</p>
<p>Strawbridge, who now lives in Houston, laid the blame on city leaders, citing “their lack of experience, their lack of knowledge, their lack of recognizing the risks” in a bumbling, decade-long endeavor to build a large seawater desalination plant that would veer the region off its clear course toward calamity.</p>
<p>“They’ve found themselves in quite a dire predicament as a result of those poor decisions,” Strawbridge said. “Time is up.”</p>
<p>A spokesperson for Corpus Christi Mayor Paulette Guajardo declined interview requests, citing “prior commitments,” and did not respond to follow-up questions. City manager Peter Zanoni also did not respond to questions. Instead, Corpus Christi public information manager Robert Gonzales provided an emailed statement.</p>
<p>“The water shortage in the Coastal Bend is the result of a historic five-year drought,” it said. “Currently, the City of Corpus Christi has $1 billion in City Council-approved and funded water projects underway to address our water needs. The City remains committed to ensuring water security for the more than 500,000 residents and our commercial and industrial customers.”</p>
<p>In an emailed statement on Monday, Gonzales called this story “an incomplete and alarmist narrative.”</p>
<p>Depletion of this region’s reservoirs would lead to “controlled depression” for the local economy, “mass unemployment” and “industrial total shutdown,” according to a two-page report by Don Roach, former assistant general manager of the San Patricio Municipal Water District, which supplies many of the region’s large industrial water users.</p>
<p>That includes refineries operated by Flint Hills Resources, Valero and Citgo that provide jet fuel to Texas airports and meet much of the state’s daily demand for gasoline.</p>
<p>“This waiting disaster is under the radar for the rest of the state,” said Roach, who worked 20 years at the water district and retired in 2014. “We hear nothing from the Texas politicians about the seriousness of the situation or any state plan to mitigate it.”</p>
<p>He no longer had access to current water data and contracts, he stressed, but produced the report based on his own knowledge. It said the costs of trucking in emergency water “would bankrupt many local small businesses and low-income households” while state emergency managers would need billions of dollars to “build emergency temporary pipelines or subsidize desalination barge rentals to prevent a total evacuation of the city.” Strawbridge, a former director of the Port of Long Beach, said Roach’s assessment was “spot on.”</p>
<p>Kara Rivas, a spokesperson for Flint Hills Resources, which delivers jet fuel via pipeline from its Corpus Christi refinery to airports in Dallas and Austin, said, “We are doing everything we can to minimize our water use and diversify our water resources to avoid disrupting our operations.”</p>
<p>Flint Hills is developing a project to use treated effluent from a wastewater treatment plant to meet up to 15 percent of its water demand. The refinery consumes about 0.55 barrels of water per barrel of crude oil, Rivas said, a 29 percent reduction since 2010. </p>
<aside class="scaip scaip-3">
</aside><p>“We are focused on working with local authorities on finding ways to meet the region’s immediate and long-term water needs,” she said. “This is a challenge that requires leadership.”</p>
<figure class="wp-block-image alignwide size-full"><img data-recalc-dims="1" width="2000" height="1333" data-attachment-id="223408" data-permalink="https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/20260303-corpus-water-crisis-icn-bd-01/" data-orig-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?fit=2560%2C1706&amp;quality=89&amp;ssl=1" data-orig-size="2560,1706" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;11&quot;,&quot;credit&quot;:&quot;Dylan Baddour/Inside Climate News&quot;,&quot;camera&quot;:&quot;Canon EOS 5D Mark III&quot;,&quot;caption&quot;:&quot;The city of Corpus Christi, on Wednesday, March 4, 2026, faces an imminent water crisis after a decades of city government failures.&quot;,&quot;created_timestamp&quot;:&quot;1772585939&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;108&quot;,&quot;iso&quot;:&quot;640&quot;,&quot;shutter_speed&quot;:&quot;0.003125&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="20260303 CORPUS WATER CRISIS ICN BD 01" data-image-description="" data-image-caption="&lt;p&gt;The city of Corpus Christi, on Wednesday, March 4, 2026, faces an imminent water crisis after a decades of city government failures.&lt;/p&gt;" data-medium-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?fit=300%2C200&amp;quality=89&amp;ssl=1" data-large-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?fit=780%2C519&amp;quality=89&amp;ssl=1" src="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1" alt="" class="wp-image-223408" srcset="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?w=2560&amp;quality=89&amp;ssl=1 2560w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=300%2C200&amp;quality=89&amp;ssl=1 300w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=1024%2C682&amp;quality=89&amp;ssl=1 1024w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=768%2C512&amp;quality=89&amp;ssl=1 768w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=1536%2C1024&amp;quality=89&amp;ssl=1 1536w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=2048%2C1365&amp;quality=89&amp;ssl=1 2048w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=1200%2C800&amp;quality=89&amp;ssl=1 1200w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1 2000w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=780%2C520&amp;quality=89&amp;ssl=1 780w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=800%2C533&amp;quality=89&amp;ssl=1 800w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?resize=400%2C267&amp;quality=89&amp;ssl=1 400w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260303-CORPUS-WATER-CRISIS-ICN-BD-01.jpg?w=370&amp;quality=89&amp;ssl=1 370w" sizes="(max-width: 2000px) 100vw, 2000px" /><figcaption class="wp-element-caption">Corpus Christi faces an imminent water crisis after a decade of city government failures, according to several former officials. Dylan Baddour/Inside Climate News</figcaption></figure>
<p>Zanoni, the city manager who has overseen Corpus Christi’s descent toward water depletion since 2019 and receives a $400,000 salary, rejected notions of imminent disaster during a <a href="https://www.youtube.com/watch?v=xk78_9qLnaY">press conference</a> Thursday, when Lake Corpus Christi, one of the city’s main reservoirs, dropped below 10%. The press conference took place three days after Inside Climate News asked the city for comment about the impending water crisis.</p>
<p>“I think we are going to get through this,” he told TV cameras as he stood before the dwindling remnants of the lake. “We have confidence in what we’re doing. This is no time to panic.”</p>
<p>Zanoni, who holds a master’s of public administration from Florida State University, said the city had “worked tirelessly over the past months to bring everything that we humanly and possibly could to forgo what could be this supply and demand issue.”</p>
<p>“Now we’re going to focus, with the city council and the region, on being prepared in case supply doesn’t meet demand,” he said.</p>
<p>“The best-case scenario, that assumes some level of rain, has this lake here going to about the early fall,” said Zanoni, who indicated that the summer months would give the city enough time to boot up its portfolio of new groundwater water projects.</p>
<aside class="scaip scaip-4">
</aside><figure class="wp-block-image size-full"><img data-recalc-dims="1" width="2000" height="1130" data-attachment-id="223409" data-permalink="https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/20260307-corpus-water-crisis-icn-bd-07/" data-orig-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?fit=2560%2C1446&amp;quality=89&amp;ssl=1" data-orig-size="2560,1446" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;City Manager Peter Zanoni, at a press conference on March 5, 2026, when Lake Corpus Christi, one of the city\u2019s main reservoirs, dropped below 10 percent.&quot;,&quot;created_timestamp&quot;:&quot;1772895708&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="20260307 CORPUS WATER CRISIS ICN BD 07" data-image-description="" data-image-caption="&lt;p&gt;City Manager Peter Zanoni, at a press conference on March 5, 2026, when Lake Corpus Christi, one of the city’s main reservoirs, dropped below 10 percent.&lt;/p&gt;" data-medium-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?fit=300%2C169&amp;quality=89&amp;ssl=1" data-large-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?fit=780%2C440&amp;quality=89&amp;ssl=1" src="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=2000%2C1130&amp;quality=89&amp;ssl=1" alt="" class="wp-image-223409" srcset="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?w=2560&amp;quality=89&amp;ssl=1 2560w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=300%2C169&amp;quality=89&amp;ssl=1 300w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=1024%2C578&amp;quality=89&amp;ssl=1 1024w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=768%2C434&amp;quality=89&amp;ssl=1 768w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=1536%2C868&amp;quality=89&amp;ssl=1 1536w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=2048%2C1157&amp;quality=89&amp;ssl=1 2048w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=1200%2C678&amp;quality=89&amp;ssl=1 1200w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=2000%2C1130&amp;quality=89&amp;ssl=1 2000w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=780%2C441&amp;quality=89&amp;ssl=1 780w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=800%2C452&amp;quality=89&amp;ssl=1 800w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?resize=400%2C226&amp;quality=89&amp;ssl=1 400w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260307-CORPUS-WATER-CRISIS-ICN-BD-07.jpg?w=370&amp;quality=89&amp;ssl=1 370w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /><figcaption class="wp-element-caption">Corpus Christi City Manager Peter Zanoni at a press conference on March 5, 2026, when Lake Corpus Christi, one of the city’s main reservoirs, dropped below 10% full.</figcaption></figure><p>James Dodson, a former director of Corpus Christi’s water department who retired this year as a private consultant and was involved in several of those projects, disagreed. He said residents and officials “are crazy not to be panicking.”</p>
<p>“It’s the very worst scenario that I’ve ever seen,” said Dodson, who oversaw a historic expansion of Corpus Christi’s water supply in the 1990s. “It’s going to be an economic disaster.”</p>
<p>For years, he said, the city dismissed repeated opportunities to develop groundwater import projects as it maintained a singular and fruitless focus on desalination. That includes projects that the city only recently scrambled to get started. Dodson doubted any will materialize in time.</p>
<p>“They’ve been kicking the can down the road for a long time and they’ve finally run out of road,” said a current regional water official who requested anonymity to preserve a working relationship with the city. “They’re looking at projects to do that they should have done five, six, seven years ago.”</p>
<p>The last hope to avert disaster, the official said, was a 20- to 30-inch rainfall.</p>
<p>“It would basically have to be a hurricane,” he said.</p>
<aside class="scaip scaip-5">
</aside><p>A spokesperson for Texas <a href="https://directory.texastribune.org/greg-abbott/" type="link" id="https://directory.texastribune.org/greg-abbott/">Gov. Greg Abbott</a>, Andrew Mahaleris, didn’t address specific comments about an impending water catastrophe or disruption of the state economy. In an emailed statement, he said: “Corpus Christi is an important economic driver not only for Texas but also the nation. The State of Texas has made significant investments into ensuring the Corpus Christi area has the water resources it needs to serve citizens and industry alike.”</p>
<p>He added that the governor “will continue working with the legislature to ensure Texans have a safe, reliable water supply for the next fifty years.”</p>
<p>Mere months remain, according to Corpus Christi’s online <a href="https://www.corpuschristitx.gov/department-directory/corpus-christi-water/water-supply-dashboard-english/">water dashboard</a>, until the city enters a “Level 1 Emergency,” which begins 180 days from projected depletion of water supplies. Functional failure of the water system, or “dead pool,” will occur before total depletion.</p>
<p>In a level one water emergency, the city’s plans call for an immediate 25% curtailment of water consumption. But city planners are only beginning to discuss what that would even look like and still haven’t determined how they would implement it.</p>
<p>“We can’t close and open everyone’s valves,” said Nick Winkelmann, chief operating officer of Corpus Christi Water, in an interview at city hall last week. “One way to enact water restrictions is through pricing.”</p>
<aside class="scaip scaip-6">
</aside><p>The region’s largest industrial users, which collectively consume the majority of the region’s water, remain exempt from emergency curtailment. These multi-billion-dollar refineries, petrochemical plants and liquified natural gas facilities are built to run at a steady rate and can’t simply throttle down production in accordance with water availability. They consume large volumes of water primarily in cooling towers to prevent excessive heating and explosions.</p>
<figure class="wp-block-image size-full"><img data-recalc-dims="1" width="2000" height="1333" data-attachment-id="223410" data-permalink="https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/20260304-corpus-water-crisis-icn-bd-05/" data-orig-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?fit=2560%2C1706&amp;quality=89&amp;ssl=1" data-orig-size="2560,1706" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;13&quot;,&quot;credit&quot;:&quot;Dylan Baddour/Inside Climate News&quot;,&quot;camera&quot;:&quot;Canon EOS 5D Mark III&quot;,&quot;caption&quot;:&quot;Gulf Coast Growth Ventures, a plastics production facility operated by Exxon Mobil and Saudi Arabia, started operations in 2022 and is the largest water consumer in the Corpus Christi region.&quot;,&quot;created_timestamp&quot;:&quot;1772670485&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;90&quot;,&quot;iso&quot;:&quot;400&quot;,&quot;shutter_speed&quot;:&quot;0.0015625&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="20260304 CORPUS WATER CRISIS ICN BD 05" data-image-description="" data-image-caption="&lt;p&gt;Gulf Coast Growth Ventures, a plastics production facility operated by Exxon Mobil and Saudi Arabia, started operations in 2022 and is the largest water consumer in the Corpus Christi region.&lt;/p&gt;" data-medium-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?fit=300%2C200&amp;quality=89&amp;ssl=1" data-large-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?fit=780%2C519&amp;quality=89&amp;ssl=1" src="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1" alt="" class="wp-image-223410" srcset="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?w=2560&amp;quality=89&amp;ssl=1 2560w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=300%2C200&amp;quality=89&amp;ssl=1 300w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=1024%2C682&amp;quality=89&amp;ssl=1 1024w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=768%2C512&amp;quality=89&amp;ssl=1 768w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=1536%2C1024&amp;quality=89&amp;ssl=1 1536w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=2048%2C1365&amp;quality=89&amp;ssl=1 2048w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=1200%2C800&amp;quality=89&amp;ssl=1 1200w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1 2000w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=780%2C520&amp;quality=89&amp;ssl=1 780w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=800%2C533&amp;quality=89&amp;ssl=1 800w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?resize=400%2C267&amp;quality=89&amp;ssl=1 400w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-05.jpg?w=370&amp;quality=89&amp;ssl=1 370w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /><figcaption class="wp-element-caption">Gulf Coast Growth Ventures, a plastics production facility operated by Exxon Mobil and Saudi Arabia’s national oil company, started operations in 2022 and is the largest water consumer in the Corpus Christi region. Dylan Baddour/Inside Climate News</figcaption></figure><p>The city also may enact across-the-board, pro-rata curtailment at will, said Winkelmann, who assumed his role last September when the city’s former water director, Drew Molly, resigned days before the city council pulled the plug on its long-running desalination project. “That will have an effect on all our customers.”</p>
<p>For years, local business leaders insisted desalination was Corpus Christi’s key to overcoming the water limitations that had historically plagued it on this semi-arid coastline. Massive desalination plants, the first of their kind in Texas, were supposed to kick off an era of abundant water, financial prosperity and limitless economic expansion.</p>
<p>Instead, the plan drove this region to the precipice of ruin.</p>
<p>“It has not gone as smoothly as it should have,” said Bob Paulison, director of the Coastal Bend Industries Association and an architect of the desalination project. “There are a lot of reasons for why that happened.” He said he worked on desalination for 12 years, but the projects got bogged down by political fights, administrative processes, the COVID pandemic and “a tug of war which has resulted in very slow progress.”</p>
<p>“I wouldn’t say that it’s a disaster,” he said of the current situation, expressing faith that the city would complete new water projects before supplies run out. It was “too early” to assess when that could happen, he said.</p>
<aside class="scaip scaip-7">
</aside><p>Presented with Roach’s report, Paulison expressed a longstanding respect for the veteran water manager but said, “It looks like it’s very dire, more dire than we’ve been looking at.”</p>
<p>“We’re relying on the model that the city has put together,” Paulison said.</p>
<p>Regarding a potential shutdown of the entire refining and petrochemical complex, he said, “that could certainly shut down at some point, but we don’t see that happening in the early stages.”</p>
<p>Asked about plans to develop alternative jet fuel supplies for Texas airports in the case of a shutdown, Paulison said, “I’m sure that someone somewhere is working on that.”</p>
<p>Charles McConnell, a former assistant energy secretary with the Obama administration, wondered why concrete plans hadn’t been prepared.</p>
<p>“Did it take them all the way to yesterday to figure out they’re going to run out by the end of the year?” he said. “That’s pretty pathetic.” McConnell, who now teaches at the University of Houston, doubted that a shutdown of Corpus Christi’s industrial sector would have acute or long-lasting impacts beyond Texas. New producers would fill the gap, while new pipelines and supply chains would bypass the city.</p>
<aside class="scaip scaip-8">
</aside><p>“It’s a surprise to me that none of those refineries and industries down there have their own desal plants,” said McConnell, who worked 31 years for the chemical manufacturer Praxair in Houston. “They’re using municipal water, for Christ’s sake!”</p>
<figure class="wp-block-image alignwide size-full"><img data-recalc-dims="1" width="2000" height="1333" data-attachment-id="223411" data-permalink="https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/20260304-corpus-water-crisis-icn-bd-02/" data-orig-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?fit=2560%2C1706&amp;quality=89&amp;ssl=1" data-orig-size="2560,1706" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;11&quot;,&quot;credit&quot;:&quot;Dylan Baddour/Inside Climate News&quot;,&quot;camera&quot;:&quot;Canon EOS 5D Mark III&quot;,&quot;caption&quot;:&quot;An ArcelorMittal iron ore plant smokes behind a playground at Simpson Park in Portland, Texas, on March 4, 2026.&quot;,&quot;created_timestamp&quot;:&quot;1772634971&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;170&quot;,&quot;iso&quot;:&quot;400&quot;,&quot;shutter_speed&quot;:&quot;0.0004&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="20260304 CORPUS WATER CRISIS ICN BD 02" data-image-description="" data-image-caption="&lt;p&gt;An ArcelorMittal iron ore plant smokes behind a playground at Simpson Park in Portland, Texas, on March 4, 2026.&lt;/p&gt;" data-medium-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?fit=300%2C200&amp;quality=89&amp;ssl=1" data-large-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?fit=780%2C519&amp;quality=89&amp;ssl=1" src="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1" alt="" class="wp-image-223411" srcset="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?w=2560&amp;quality=89&amp;ssl=1 2560w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=300%2C200&amp;quality=89&amp;ssl=1 300w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=1024%2C682&amp;quality=89&amp;ssl=1 1024w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=768%2C512&amp;quality=89&amp;ssl=1 768w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=1536%2C1024&amp;quality=89&amp;ssl=1 1536w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=2048%2C1365&amp;quality=89&amp;ssl=1 2048w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=1200%2C800&amp;quality=89&amp;ssl=1 1200w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1 2000w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=780%2C520&amp;quality=89&amp;ssl=1 780w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=800%2C533&amp;quality=89&amp;ssl=1 800w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?resize=400%2C267&amp;quality=89&amp;ssl=1 400w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-02.jpg?w=370&amp;quality=89&amp;ssl=1 370w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /><figcaption class="wp-element-caption">An iron ore plant behind a playground at Simpson Park in Portland, near Corpus Christi, on March 4, 2026. Dylan Baddour/Inside Climate News</figcaption></figure>
<p>The roots of this situation stretch back more than a decade, to the period of rapid downstream industrial expansion that followed the shale revolution in the oilfields of Texas. Strawbridge joined the Port of Corpus Christi Authority in 2015, as a surge of major industrial projects sought to build in the area. Even then, Strawbridge said, everyone knew Corpus Christi needed more water.</p>
<p>In January 2016, Abbott <a href="https://gov.texas.gov/news/post/governor_abbott_attends_luncheon_with_israeli_business_leaders">traveled to Israel,</a> where he toured the world’s largest seawater desalination plant and met with Israeli officials to discuss desalination.</p>
<p>Later that year, an industry group called H2O4Texas, with <a href="https://docs.google.com/presentation/d/1lceStZIe-bDyN7P0PfWtZju_fnh7A0D2/edit?usp=sharing&amp;ouid=115167961506787936390&amp;rtpof=true&amp;sd=true">sponsors</a> including Dow, Chevron and Marathon Oil, hosted <a href="https://www.texastribune.org/2016/07/12/event-texas-water-tour-corpus-christi/">an event</a> in Corpus Christi. “They were basically saying because of the growth in the Coastal Bend, we were gonna need desalination,” said Isabel Araiza, then a professor at Texas A&amp;M University-Corpus Christi, who attended the event.</p>
<p>That was the first that Araiza, a Corpus Christi native with a Ph.D. from Boston University, had heard of desalination. She said she was at the meeting for a different reason, finding it strange how many business and political leaders were there.</p>
<p>The oil and gas industry wanted to build enormous projects in the region, processing oil and gas from Texas’ shale fields into myriad fuels, chemicals and plastics before loading them onto tankers for export.</p>
<aside class="scaip scaip-9">
</aside><p>In March 2017, then-city manager Margie Rose sent <a href="https://drive.google.com/file/d/13FYYsvgvbu7-zMfImnNFYPKs42QZ_72o/view?usp=sharing">a letter</a> to ExxonMobil, the world’s largest private oil company, that said, “because the City aggressively protects water resources for the future by implementing a matrix of supply strategies, we feel that we have sufficient water supplies to meet your needs.”</p>
<p>Six days later the city <a href="https://drive.google.com/file/d/15siBmfuqpev50Eg0pZ6mhyVA7Q0XBFfn/view?usp=sharing">requested funding</a> from the Texas Water Development Board to study feasibility and do preliminary design of a seawater desalination plant.</p>
<p>Around that time, Strawbridge said, “it became very clear to the port authority that there was a difference of opinions as to how much water was available and how much would be needed to continue to attract large industrial investors.”</p>
<p>“The city felt that it had enough water to last, based on its forecast, until 2040,” Strawbridge said. “We, the port authority, had a very different view of what that demand curve looked like.”</p>
<p>That’s when the port began developing plans for its own desalination plant, he said.</p>
<p>In 2018, a new, interim city manager, Keith Selman, <a href="https://drive.google.com/file/d/1-H5fSJydznLHqHbI0j4U4BS1rYXnQzhS/view?usp=sharing">promised another large volume of water</a> to Steel Dynamics, which then built a steel mill in the area.</p>
<p>That same year, Corpus Christi created a program exempting the region’s largest industrial water users from water curtailment restrictions during drought for a fee of $0.25 per 1,000 gallons. The city said it would use the money to fund the development of a new water source. The city’s water reservoirs were two-thirds full at the time.</p>
<p>Gonzales, the city public information officer, said the industrial water users are subject to mandatory state 1, 2, and 3 restrictions of the city’s Drought Contingency Plan, but described the <a href="https://drive.google.com/file/d/1637xf6L5J91gb20TttHY8cPJOThGG9yH/view">Drought Surcharge Exemption Fee</a> as “a payment structure, not a regulatory waiver.” </p>
<p>“To claim they are ‘exempt’ from curtailment is a fundamental misinterpretation of the city code,” he said.</p>
<p>In 2019, the city’s staff presented the city council with a plan to build a seawater desalination facility. Exxon had taken up the city’s offer for water and planned to build a massive plastics plant called Gulf Coast Growth Ventures in partnership with Saudi Arabia’s national oil company. It would be the largest water user in the region, consuming as much as all city residents combined.</p>
<p>“Large increases in water demand are projected to occur in 2022,” said a presentation given to the city council by then-Assistant City Manager Mark Van Vleck. “To meet expected water demand, we need to move forward with the procurement of a seawater desalination plant now.”</p>
<p>The plant would produce 10 million gallons per day, cost $140 million and take two years to build, the presentation said. It needed to begin supplying water by the start of 2023. The council voted unanimously to move forward.</p>
<p>By 2020 the size of the proposed plant had doubled. “We were recognizing that we’re going to need more water,” said Roland Barrera, a city council member who has served since 2018. “If we want to expand our economy, then we have to recognize that’s the way to go.”</p>
<p>As the scale of the situation came into focus, the city proposed a second desalination plant, and the port also proposed two.</p>
<figure class="wp-block-image size-large"><img data-recalc-dims="1" width="1024" height="682" data-attachment-id="223413" data-permalink="https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/20260304-corpus-water-crisis-icn-bd-04/" data-orig-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?fit=2560%2C1706&amp;quality=89&amp;ssl=1" data-orig-size="2560,1706" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;11&quot;,&quot;credit&quot;:&quot;Dylan Baddour/Inside Climate News&quot;,&quot;camera&quot;:&quot;Canon EOS 5D Mark III&quot;,&quot;caption&quot;:&quot;Encarnacion Serna, a retired chemical engineer, explains a diagram and calculations he made of one of the city\u2019s desalination projects.&quot;,&quot;created_timestamp&quot;:&quot;1772641921&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;40&quot;,&quot;iso&quot;:&quot;1000&quot;,&quot;shutter_speed&quot;:&quot;0.01&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="20260304 CORPUS WATER CRISIS ICN BD 04" data-image-description="" data-image-caption="&lt;p&gt;Encarnacion Serna, a retired chemical engineer, explains a diagram and calculations he made of one of the city’s desalination projects.&lt;/p&gt;" data-medium-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?fit=300%2C200&amp;quality=89&amp;ssl=1" data-large-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?fit=780%2C519&amp;quality=89&amp;ssl=1" src="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=1024%2C682&amp;quality=89&amp;ssl=1" alt="" class="wp-image-223413" srcset="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=1024%2C682&amp;quality=89&amp;ssl=1 1024w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=300%2C200&amp;quality=89&amp;ssl=1 300w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=768%2C512&amp;quality=89&amp;ssl=1 768w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=1536%2C1024&amp;quality=89&amp;ssl=1 1536w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=2048%2C1365&amp;quality=89&amp;ssl=1 2048w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=1200%2C800&amp;quality=89&amp;ssl=1 1200w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1 2000w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=780%2C520&amp;quality=89&amp;ssl=1 780w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=800%2C533&amp;quality=89&amp;ssl=1 800w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04.jpg?resize=400%2C267&amp;quality=89&amp;ssl=1 400w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-04-1024x682.jpg?w=370&amp;quality=89&amp;ssl=1 370w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Encarnacion Serna, a retired chemical engineer, explains a diagram and calculations he made of one of the city’s desalination projects. Dylan Baddour/Inside Climate News</figcaption></figure>
<p>That’s when Encarnacion Serna, a retired chemical plant operations manager, found out about plans for one of those plants just up the shore from his waterfront home on Corpus Christi Bay.</p>
<p>Serna, an engineer who had worked on reverse osmosis water systems for Valero and Occidental Chemical, reviewed the project’s application. What he saw, he said, astounded him: flimsy assumptions, unrealistic estimates and missing information.</p>
<p>A facility of that scale, he knew, would require railcars full of pretreatment chemicals, create a mountain of sludge waste every day and consume a tremendous amount of electricity. But he didn’t see serious plans for any of that, he said.</p>
<p>He dug deeper into the desalination boom and quickly saw what was going on: Politicians and businessmen had oversold their water supply, he said, and were scrambling for more as shortages approached. But none of them had any idea what they were doing, Serna remembered thinking as he reviewed the applications.</p>
<p>“I’ve been trying since 2020 to let them know how catastrophic this is going to be,” he said in an interview at his home. “They’ve acted with a profound ignorance.”</p>
<p>Serna, a father of four who worked his whole life at chemical plants in Texas, didn’t think any of the proposals would produce as much freshwater as projected, come online as quickly as expected or cost as little as any of the applications stated. These were not going to solve the crisis that officials had teed up, he believed.</p>
<p>In calls, emails and public comments to city and port officials, Serna raised the alarm at what he saw unfolding. He felt brushed off and soon stopped receiving responses.</p>
<p>Serna knew that chemical plants and refineries can’t just throttle down water consumption at will. The multi-billion-dollar facilities are meant to operate consistently at a steady state with a set inflow of water. Changing that balance raised risks of explosions. The whole region was skidding toward catastrophe, Serna thought at the time, with no realistic solution in sight.</p>
<p>In 2022, Gulf Coast Growth Ventures, the Exxon-Saudi partnership, began to draw water while the desalination facility meant to supply it still didn’t even exist on paper.</p>
<p>Strawbridge, then CEO of the Port of Corpus Christi Authority, insisted a private desalination operator should build and run a large facility that could sell its water to the city. But the city wanted to operate its own. Strawbridge considered the location of the city’s project unsuitable. Both sides said the other took steps to undermine the project.</p>
<p>Meanwhile, veteran local scientists rejected envrionmental studies from developers claiming the massive discharge of brine from the plants wouldn’t turn the coastal bays and estuaries into hypersaline wastelands.</p>
<p>“I’ve read the engineering studies,” said Paul Montagna, an endowed chair at the Harte Institute for Gulf of Mexico Studies at Texas A&amp;M University in Corpus Christi, in a <a href="https://insideclimatenews.org/news/04112022/corpus-christi-texas-exxon-water-desalination/">2022 interview</a> with Inside Climate News. “And I just don’t get it.”</p>
<p>Environmentalists organized against the plants. Araiza, the college professor who attended the first desalination meeting, had become a leader among groups that were fighting desalination as a means to resist the onslaught of petrochemical projects in their area, which they saw as wealthy, outside interests swooping in to hijack their resources, institutions and environment. <br /></p>
<p>“They really thought it was just going to be a yes,” she said from her office at Del Mar College, beneath a poster of Che Guevara. “I think we helped slow things down.” </p>
<p>Barrera, the city council member, started to feel uneasy as controversy and constant turnover on the council seemed to leave them unable to push the project forward.</p>
<p>“I’ve been accused of being a fearmonger,” he said in an interview at his office in downtown Corpus Christi. “Now everybody’s scared.”</p>
<figure class="wp-block-image alignwide size-full"><img data-recalc-dims="1" width="2000" height="1333" data-attachment-id="223414" data-permalink="https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/20260304-corpus-water-crisis-icn-bd-03/" data-orig-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?fit=2560%2C1706&amp;quality=89&amp;ssl=1" data-orig-size="2560,1706" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;11&quot;,&quot;credit&quot;:&quot;Dylan Baddour/Inside Climate News&quot;,&quot;camera&quot;:&quot;Canon EOS 5D Mark III&quot;,&quot;caption&quot;:&quot;Encarnacion Serna, on March 4, 2026, at his home on Corpus Christi Bay, spent years trying to warn local officials that they were steering the region towards disaster.&quot;,&quot;created_timestamp&quot;:&quot;1772640700&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;40&quot;,&quot;iso&quot;:&quot;1000&quot;,&quot;shutter_speed&quot;:&quot;0.00625&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="20260304 CORPUS WATER CRISIS ICN BD 03" data-image-description="" data-image-caption="&lt;p&gt;Encarnacion Serna, on March 4, 2026, at his home on Corpus Christi Bay, spent years trying to warn local officials that they were steering the region towards disaster.&lt;/p&gt;" data-medium-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?fit=300%2C200&amp;quality=89&amp;ssl=1" data-large-file="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?fit=780%2C519&amp;quality=89&amp;ssl=1" src="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1" alt="" class="wp-image-223414" srcset="https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?w=2560&amp;quality=89&amp;ssl=1 2560w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=300%2C200&amp;quality=89&amp;ssl=1 300w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=1024%2C682&amp;quality=89&amp;ssl=1 1024w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=768%2C512&amp;quality=89&amp;ssl=1 768w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=1536%2C1024&amp;quality=89&amp;ssl=1 1536w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=2048%2C1365&amp;quality=89&amp;ssl=1 2048w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=1200%2C800&amp;quality=89&amp;ssl=1 1200w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=2000%2C1333&amp;quality=89&amp;ssl=1 2000w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=780%2C520&amp;quality=89&amp;ssl=1 780w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=800%2C533&amp;quality=89&amp;ssl=1 800w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?resize=400%2C267&amp;quality=89&amp;ssl=1 400w, https://i0.wp.com/www.texastribune.org/wp-content/uploads/2026/03/20260304-CORPUS-WATER-CRISIS-ICN-BD-03.jpg?w=370&amp;quality=89&amp;ssl=1 370w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /><figcaption class="wp-element-caption">Encarnacion Serna, at his home on Corpus Christi Bay in March, spent years trying to warn local officials that they were steering the region toward disaster. Dylan Baddour/Inside Climate News</figcaption></figure>
<p>Strawbridge took an entourage of about 30 Texas lawmakers, businessmen and lobbyists to Israel in November 2022 to visit desalination facilities “to see that it is possible to solve for our water issues,” he said.</p>
<p>Strawbridge encouraged the lawmakers to support the port’s development of a private desalination plant, which he said was urgently needed to cover for the failures of the city. But he drew <a href="https://www.caller.com/story/news/2022/04/20/city-against-port-corpus-christis-desalination-loan-application/7381667001/">public outrage</a> from city officials when he applied for state funding for a facility that struck them as a competitor to theirs.</p>
<p>Strawbridge said the trip to Israel ultimately led the Texas lawmakers to pass legislation in 2023 that created the state’s $1 billion water fund.</p>
<p>But the trip, not disclosed to the public at the time, ultimately ignited a scandal that led to Strawbridge’s resignation when <a href="https://www.kristv.com/news/6-investigates/6-investigates-digging-into-expenses-by-port-of-corpus-christis-executive-director">an investigation</a> by KRIS 6 revealed that the port, which is not a taxing entity, spent more than $200,000 taking the crew to Israel. The station described “a pattern of lavish spending” on that trip and in prior port activities.</p>
<p>Strawbridge earned $750,000 in the prior year and had expensed an average of $10,000 per month on food and alcohol, including parties. One day later, Strawbridge resigned, but maintained that all expenses were incurred properly through his work representing the port.</p>
<p>In an interview, he characterized the report and scandal as “a hit job” by political opponents and “an effort to hasten my departure from the Port.”</p>
<p>“They used the expenses from the Israel trip as a basis for smearing my good name, although the trip ultimately proved fortuitous for the state and its water funding,” Strawbridge said. “Ultimately an independent audit of the previous five years of my expenses found absolutely no irregularities or departures from policy. But of course that wasn’t covered by KRIS 6.”</p>
<p>That year, 2023, was the hottest on record in Texas. Water levels in Corpus Christi reservoirs continued to plummet as the drought intensified. Desalination had moved to the center of Corpus Christi’s public conversation. Local politicians spoke for or against it while activists flocked to city council meetings and permit hearings.</p>
<p>“Blessed be the environmentalists,” said Serna, the retired engineer. “But 90% of them don’t know what the hell they’re talking about.”</p>
<p>In January 2024, Corpus Christi City Council produced a new cost estimate for its proposed desalination plant of about $550 million to produce 30 million gallons of freshwater per day.</p>
<p>“These numbers are ridiculously low, fraudulent and deceitful,” Serna wrote in an email to city officials.</p>
<p>By that time, Serna was angry. The subject line of his email read: “The Legacy of the Imbeciles.”</p>
<p>Where was the city even getting this cost estimate from, he asked, if it “does not have engineering and construction drawings.”</p>
<p>“All the city has at this time are deficits and bills incurred by lunatics in the millions of dollars already spent in the pursuit of this Scam project with nothing tangible on hand yet,” Serna wrote.</p>
<p>Later that year, a new cost estimate put the project at nearly $760 million. Another estimate, in July 2025, said $1.2 billion.</p>
<p>Two months later, Corpus Christi City Council, dominated by newly elected members and unable to stomach the cost, voted to cancel the project after a rancorous, 12-hour public meeting that broke repeatedly into yelling from the audience.</p>
<p>By then, the Port of Corpus Christi Authority also handed off one of its desalination projects to the nearby Nueces River Authority and mothballed another.</p>
<p>Corpus Christi city leaders expressed optimism over plans to quickly pipe in groundwater from the Evangeline Aquifer about 20 miles away. But when users of that water, like the small city of Sinton, requested in February 2026 that an administrative law judge review Corpus Christi’s groundwater permits, hope faded for a timely solution, other than hurricane-scale rainfall.</p>
<p>“Let the shit hit the fan,” said Serna. “Let dog eat dog.”</p>
<p>What does he think will happen to Corpus Christi? In time, he said, the refineries and chemical plants will probably build their own water projects, somehow, and possibly restart their facilities that they will have to mothball in the meantime. For residents, he said, life might be like it used to be for him, 70 years ago, as a boy in the Rio Grande Valley, when he would hang plastic jugs on mesquite branches and carry them on his shoulder to ask nearby companies for water.</p>
<p>“This is the legacy of the imbeciles,” he said.</p>
<p>In an emailed statement following publication of this report, Gonzales listed the projects the city is pursuing to produce more water and alleviate the crisis. </p>
<p>He said that the city is <a href="https://www.texastribune.org/2025/01/23/texas-corpus-christi-water-emergency-reservoirs/">drilling emergency water wells</a> along the Nueces River. Experts interviewed <a href="https://photos.app.goo.gl/Eps5Z1rZ7LKbG49U6">don’t expect</a> those wells to produce significant volumes before <a href="https://www.corpuschristitx.gov/department-directory/corpus-christi-water/water-supply-dashboard-english/">the city projects</a> it may run out of water by early fall. </p>
<p>Gonzales also said the city was pursuing its Evangeline Groundwater program. Dodson, who was involved with that project, said the city repeatedly dismissed it for years until 2025 when the situation became dire.</p>
<p>A <a href="https://drive.google.com/file/d/1yN7f6LaMNTjYbt0xzHKi1w5pPGREaQ51/view?usp=sharing">challenge to that project’s permits</a> was filed in February by the city of Sinton, which said “the transport and production of groundwater representing more than four times the total current production of all groundwater users in San Patricio County, is likely to result in unreasonable water level declines.” <br />Gonzales also said that the Corpus Christi City Council, in February, <a href="https://www.kiiitv.com/article/news/local/corpus-christi-city-council-approves-11-items-including-evangeline-groundwater-agreements/503-53679704-4d2d-4554-aac9-37c501271223">approved plans</a> for a seawater desalination plant that the city projects will begin producing potable water in two years. </p>
<p><em>Disclosure: Texas A&amp;M University, the University of Houston and Valero have been financial supporters of The Texas Tribune, a nonprofit, nonpartisan news organization that is funded in part by donations from members, foundations and corporate sponsors. Financial supporters play no role in the Tribune’s journalism. Find a complete <a href="https://www.texastribune.org/support-us/corporate-sponsors/">list of them here</a>.</em></p>
<div class="wp-block-group newspack-corrections-module corrections-low-module">
<p class="correction"><a class="correction-title" href="https://www.texastribune.org/corrections/">Correction, March 9, 2026, 5:50 p.m. Central:</a><br />A previous version of this story incorrectly said Bob Paulison was a member of the Texas Chemistry Council and the architect of Corpus Christi’s desalination project. He was not a member of the council and not the sole architect of the project.</p>
</div>
<section id="block-39" class="below-content widget widget_block">
</section><section id="block-31" class="below-content widget widget_block"><div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-33975377 wp-block-group-is-layout-flex c25">
<div class="wp-block-group wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained c24">
<figure class="wp-block-image is-resized"><img width="23" height="22" src="https://www.texastribune.org/wp-content/uploads/2025/09/trust-indicator.svg" alt="" class="wp-image-185171 c23" /></figure></div>
<p> <em><a href="https://www.texastribune.org/about/privacy-policy/">Learn about The Texas Tribune’s policies</a>, including our partnership with <a href="https://www.texastribune.org/about/#trust-project">The Trust Project</a> to increase transparency in news.</em></p>
</div>
</section><section id="block-44" class="below-content widget widget_block"><aside><div class="newspack-popup-container newspack-popup hidden newspack-inline-popup newspack-lightbox-no-border wp-block-group prompt-membership-text wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained c34" role="button" tabindex="0" id="id_16" data-segments="4" data-frequency="0,0,0,month">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex">
<p class="c27"><strong><em>You've read</em></strong> <strong><em><mark class="has-inline-color c26"> article</mark> this month. You have unlimited free articles remaining because we don't have a paywall.</em></strong></p>
<p class="c27"><strong>Texans need the truth. Help us report it.</strong></p>
<p>Independent Texas reporting needs your support. The Texas Tribune delivers fact-based journalism for Texans, by Texans — and our community of members, the readers who donate, make our work possible. Help us bring you and millions of others in-depth news and information. Will you support our nonprofit newsroom with a donation of any amount?</p>
</div>
<div class="wp-block-group is-style-border is-vertical is-content-justification-stretch is-layout-flex wp-container-core-group-is-layout-b16ad781 wp-block-group-is-layout-flex">
<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex c30">
<h3 class="wp-block-heading c28">Support Independent Texas News</h3>
<p class="font-sansserif c29">Choose an amount or <a href="https://www.texastribune.org/about/#texastribune-membership">learn more about membership</a>.</p>
</div>
</div>
<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex wp-block-button has-custom-width wp-block-button__width-100 c30"><a class="wp-block-button__link has-dark-gray-color has-primary-background-color has-text-color has-background has-link-color wp-element-button" href="https://support.texastribune.org/donate?utm_medium=site&amp;utm_source=EOACTA&amp;installmentPeriod=yearly&amp;amount=200&amp;campaignId=7016f000002GvLdAAK">Donate Now</a></div>
</div>
</div>
</aside></section><section id="block-45" class="below-content widget widget_block"><aside><div class="newspack-popup-container newspack-popup hidden newspack-inline-popup newspack-lightbox-no-border wp-block-group prompt-membership-text wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained c34" role="button" tabindex="0" id="id_13" data-segments="5" data-frequency="0,0,0,month">
<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex">
<p class="c27"><strong><em>You've read</em></strong> <strong><em><mark class="has-inline-color c26"> articles</mark> this month. You have unlimited free articles remaining because we don't have a paywall.</em></strong></p>
<p class="c27"><strong>Texans need the truth. Help us report it.</strong></p>
<p>Independent Texas reporting needs your support. The Texas Tribune delivers fact-based journalism for Texans, by Texans — and our community of members, the readers who donate, make our work possible. Help us bring you and millions of others in-depth news and information. Will you support our nonprofit newsroom with a donation of any amount?</p>
</div>
<div class="wp-block-group is-style-border is-vertical is-content-justification-stretch is-layout-flex wp-container-core-group-is-layout-b16ad781 wp-block-group-is-layout-flex">
<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex c30">
<h3 class="wp-block-heading c28">Support Independent Texas News</h3>
<p class="font-sansserif c29">Choose an amount or <a href="https://www.texastribune.org/about/#texastribune-membership">learn more about membership</a>.</p>
</div>
</div>
<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex wp-block-button has-custom-width wp-block-button__width-100 c30"><a class="wp-block-button__link has-dark-gray-color has-primary-background-color has-text-color has-background has-link-color wp-element-button" href="https://support.texastribune.org/donate?utm_medium=site&amp;utm_source=EOACTA&amp;installmentPeriod=yearly&amp;amount=200&amp;campaignId=7016f000002GvLdAAK">Donate Now</a></div>
</div>
</div>
</aside></section>]]></description>
      <link>https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/</link>
      <guid>https://www.texastribune.org/2026/03/08/texas-corpus-christi-water-crisis/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Welcome • freemediaheckyeah]]></title>
      <description><![CDATA[<div class="fixed inset-0 z-[99999] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm p-6 rounded-xl shadow-2xl max-w-md w-full c1"><h2 class="text-xl font-bold mb-4 flex items-center gap-2">Base64 Encoded Link</h2><p class="mb-4 text-text-1">The link you clicked leads to a Base64 encoded string.</p><p class="mb-2 text-text-1">To decode it, you can use:</p><ul class="list-disc list-inside mb-4 space-y-2 text-text-1"><li>An online tool: <a href="https://www.base64decode.org/" target="_blank" rel="noreferrer" class="text-primary hover:underline font-medium">Base64 Decode</a></li>
<li>A userscript: <a href="https://greasyfork.org/en/scripts/485772-fmhy-base64-auto-decoder" target="_blank" rel="noreferrer" class="text-primary hover:underline font-medium">FMHY Base64 Auto Decoder</a> (using a <a href="https://fmhy.net/internet-tools#userscripts" target="_blank" class="text-primary hover:underline font-medium">userscript manager</a>)</li>
</ul><p class="mb-6 text-sm text-text-2">For more options: <a href="https://fmhy.net/text-tools#encode-decode" target="_blank" class="text-primary hover:underline font-medium">Base64 Decoders</a></p><p><label for="dont-show" class="text-sm text-text-1 select-none">Don't show again</label></p></div><p>FMHY</p>
<div class="content" data-v-7abf9a92="">✴️ rss.fmhy</div>
<p> SearXNG Site Hunting SFW FMHY Selfhosting Wallpapers Feedback</p>
<div class="VPContent is-home VPHome" id="VPContent" data-v-4f666062="" data-v-0df4f7eb=""><div class="VPHero has-image VPHomeHero container" data-v-d4ed7c74="" data-v-1c0f73f6=""><div class="image image-container" data-v-1c0f73f6=""><img class="VPImage image-src" src="https://fmhy.net/test.png" alt="FMHY Icon" data-v-a5871d3f="" /></div></div><div class="VPFeatures VPHomeFeatures container" data-v-d4ed7c74="" data-v-e76166b6=""><div class="items" data-v-e76166b6=""><article class="box" data-v-ebff9d21=""><div class="icon" data-v-ebff9d21="">Ad-block / Privacy</div><h2 class="title" data-v-ebff9d21="">Adblocking / Privacy</h2><p class="details" data-v-ebff9d21="">Learn how to block ads, trackers and other nasty things.</p></article></div></div></div>]]></description>
      <link>https://fmhy.net/</link>
      <guid>https://fmhy.net/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Trump DoD Axed a Program Meant to Limit Civilian Casualties — ProPublica]]></title>
      <description><![CDATA[<div class="wp-block-propublica-reporting-highlights"><ul class="wp-block-list"><li><strong>Civilian Harm:</strong> In the opening days of the war with Iran, missile strikes have already killed civilians, including scores of schoolchildren.</li>
<li><strong>Blueprint Stalled:</strong> The Pentagon had been working on a plan to avoid civilian deaths. It was heading toward implementation until Trump officials waylaid it last year.</li>
<li><strong>Scant Accountability:</strong> With the plan to reduce civilian deaths sidelined, experts say the U.S. military plans face limited scrutiny before attacks are launched.</li>
</ul><p class="wp-block-propublica-reporting-highlights__disclaimer">These highlights were written by the reporters and editors who worked on this story.</p></div><figure class="wp-block-propublica-iframe bb--size-small-right">
</figure><p>Images from the missile strike in southern Iran were more horrifying than any of the case studies Air Force combat veteran Wes J. Bryant had pored over in his mission to overhaul how the U.S. military safeguards civilian life.</p><p>Parents wept over their children’s bodies. Crushed desks and blood-stained backpacks poked through the rubble. The death toll from the attack on an elementary school in Minab climbed past 165, most of them under age 12, with nearly 100 others wounded, according to Iranian health officials. Photos of small coffins and rows of fresh graves went viral, a devastating emblem of Day 1 in the open-ended U.S.-Israeli war in Iran.</p><p>Bryant, a former special operations targeting specialist, said he couldn’t help but think of what-ifs as he monitored fallout from the Feb. 28 attack.</p><p>Just over a year ago, he had been a senior adviser in an ambitious new Defense Department program aimed at reducing civilian harm during operations. Finally, Bryant said, the military was getting serious about reforms. He worked out of a newly opened Civilian Protection Center of Excellence, where his supervisor was a veteran strike-team targeter who had served as a United Nations war crimes investigator.</p><p>Today, that momentum is gone. Bryant was forced out of government in cuts last spring. The civilian protection mission was dissolved as Defense Secretary Pete Hegseth made “lethality” a top priority. And the world has witnessed a tragedy in Minab that, if U.S. responsibility is confirmed, would be the most civilians killed by the military in a single attack in decades.</p><p>Dismantling the fledgling harm-reduction effort, defense analysts say, is among several ways the Trump administration has reorganized national security around two principles: more aggression, less accountability.</p><p>Trump and his aides lowered the authorization level for lethal force, broadened target categories, inflated threat assessments and fired inspectors general, according to more than a dozen current and former national security personnel. Nearly all spoke on condition of anonymity for fear of retaliation.</p><p>“We’re departing from the rules and norms that we’ve tried to establish as a global community since at least World War II,” Bryant said. “There’s zero accountability.”</p><p>Citing open-source intelligence and government officials, several news outlets <a href="https://www.nytimes.com/2026/03/05/world/middleeast/iran-school-us-strikes-naval-base.html">have concluded</a> that the strike in Minab most likely was carried out by the United States. President Donald Trump, without providing evidence, <a href="https://www.politico.com/news/2026/03/07/trump-iran-girls-school-strike-00818163">told reporters</a> March 7 that it was “done by Iran.” Hegseth, standing next to the president aboard Air Force One, said the matter was under investigation.</p><p>The next day, the open-source research outfit Bellingcat said it had <a href="https://www.bellingcat.com/news/2026/03/08/video-shows-us-tomahawk-missile-strike-next-to-girls-school-in-iran/">authenticated a video</a> showing a Tomahawk missile strike next to the school in Minab. Iranian state media later <a href="https://www.nytimes.com/2026/03/09/world/middleeast/iran-school-strike-us-missile.html">showed fragments</a> of a U.S.-made Tomahawk, as identified by Bellingcat and others, at the site. The United States is the only party to the conflict known to possess Tomahawks. U.N. human rights experts have <a href="https://www.ohchr.org/en/press-releases/2026/03/un-experts-strongly-condemn-deadly-missile-strike-girls-school-iran-call">called for an investigation</a> into whether the attack violated international law.</p><p>The Department of Defense and White House did not respond to requests for comment.</p><p>Since the post-9/11 invasions of Afghanistan and Iraq, successive U.S. administrations have faced <a href="https://mwi.westpoint.edu/ten-years-after-the-al-awlaki-killing-a-reckoning-for-the-united-states-drones-wars-awaits/">controversies over civilian deaths</a>. Defense officials eager to shed the legacy of the “forever wars” have periodically called for better protections for civilians, but there was no standardized framework until 2022, when Biden-era leaders adopted a strategy rooted in work that had begun under the first Trump presidency.</p><p>Formalized in a 2022 <a href="https://media.defense.gov/2022/Aug/25/2003064740/-1/-1/1/CIVILIAN-HARM-MITIGATION-AND-RESPONSE-ACTION-PLAN.PDF">action plan</a> and in a <a href="https://www.esd.whs.mil/Portals/54/Documents/DD/issuances/dodi/300017p.pdf">Defense Department instruction</a>, the initiatives are known collectively as Civilian Harm Mitigation and Response, a clunky name often shortened to CHMR and pronounced “chimmer.” Around 200 personnel were assigned to the mission, including roughly 30 at the Civilian Protection Center of Excellence, a coordination hub near the Pentagon.</p><p>The CHMR strategy calls for more in-depth planning before an attack, such as real-time mapping of the civilian presence in an area and in-depth analysis of the risks. After an operation, reports of harm to noncombatants would prompt an assessment or investigation to figure out what went wrong and then incorporate those lessons into training.</p><p>By the time Trump returned to power, harm-mitigation teams were embedded with regional commands and special operations leadership. During Senate confirmation hearings, several Trump nominees for top defense posts <a href="https://civiliansinconflict.org/blog/us-military-voices-speak-out-in-support-of-civilian-protection">voiced support</a> for the mission. Once in office, however, they stood by as the program was gutted, current and former national security officials said.</p><p>Around 90% of the CHMR mission is gone, former personnel said, with no more than a single adviser now at most commands. At Central Command, where a 10-person team was cut to one, “a handful” of the eliminated positions were backfilled to help with the Iran campaign. Defense officials can’t formally close the Civilian Protection Center of Excellence without congressional approval, but Bryant and others say it now exists mostly on paper.</p><p>“It has no mission or mandate or budget,” Bryant said.</p><p>Global conflict monitors have since recorded a dramatic increase in deadly U.S. military operations. Even before the Iran campaign, the number of strikes worldwide since Trump returned to office had <a href="https://acleddata.com/media-citation/revealed-trump-has-launched-many-air-strikes-five-months-biden-did-four-years">surpassed the total</a> from all four years of Joe Biden’s presidency.</p><p>Had the Defense Department’s harm-reduction mission continued apace, current and former officials say, the policies almost certainly would’ve reduced the number of noncombatants harmed over the past year.</p><p>Beyond the moral considerations, they added, civilian casualties fuel militant recruiting and hinder intelligence-gathering. Retired Gen. Stanley McChrystal, who commanded U.S. and NATO forces in Afghanistan, explains the risk in an equation he calls “<a href="https://www.bbc.com/news/10398425">insurgent math</a>”: For every innocent killed, at least 10 new enemies are created.</p><p>U.S.-Israeli strikes have already killed more than 1,200 civilians in Iran, including nearly 200 children, <a href="https://www.en-hrana.org/day-nine-of-the-u-s-israeli-war-on-iran-polluted-air-and-black-rain-in-tehran/">according to Human Rights Activists News Agency</a>, a U.S.-based group that verifies casualties through a network in Iran. The group says hundreds more deaths are under review, a difficult process given Iran’s internet blackout and dangerous conditions.</p><figure class="wp-block-image size-propublica-position-medium bb--size-medium"><img height="564" width="752" src="https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?w=752" alt="A person in a crowd holds up an image of two young girls posing together, smiling and dressed in green uniforms." class="wp-image-69967" srcset="https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg 2560w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=300,225 300w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=768,576 768w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=1024,768 1024w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=1536,1152 1536w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=2048,1536 2048w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=863,647 863w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=422,317 422w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=552,414 552w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=558,419 558w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=527,395 527w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=752,564 752w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=1149,862 1149w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=2000,1500 2000w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=400,300 400w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=800,600 800w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=1200,900 1200w, https://www.propublica.org/wp-content/uploads/2026/03/GettyImages-2263976189.jpg?resize=1600,1200 1600w" sizes="(max-width: 752px) 100vw, 752px" /><figcaption class="attribution">A mourner holds a portrait of students during a funeral held after a school in Iran’s Hormozgan province was bombed. Thousands attended the ceremony. Stringer/Anadolu via Getty Images</figcaption></figure><p>Defense analysts say the civilian toll of the Iran campaign, on top of dozens of recent noncombatant casualties in Yemen and Somalia, reopens dark chapters from the “war on terror” that had prompted reforms in the first place.</p><p>“It’s a recipe for disaster,” a senior counterterrorism official who left the government a few months ago said of the Trump administration’s yearlong bombing spree. “It’s ‘Groundhog Day’ — every day we’re just killing people and making more enemies.”</p><p>In 2015, twodozen patients and 14 staff members were killed when a heavily armed U.S. gunship fired for over an hour on a Doctors Without Borders hospital in northern Afghanistan, a disaster that has become a cautionary tale for military planners.</p><p>“Our patients burned in their beds, our medical staff were decapitated or lost limbs. Others were shot from the air while they fled the burning building,” the international aid group said <a href="https://www.msf.org/kunduz-hospital-attack-depth">in a report</a> about the destruction of its trauma center in Kunduz.</p><p>A <a href="https://www.centcom.mil/MEDIA/PRESS-RELEASES/Press-Release-View/Article/904574/april-29-centcom-releases-investigation-into-airstrike-on-doctors-without-borde/">U.S. military investigation</a> found that multiple human and systems errors had resulted in the strike team mistaking the building for a Taliban target. The Obama administration apologized and offered <a href="https://www.npr.org/2016/04/11/473772669/survivors-of-afghan-hospital-airstrike-dissatisfied-with-compensation-plan">payouts of $6,000</a> to families of the dead.</p><p>Human rights advocates had hoped the Kunduz debacle would force the U.S. military into taking concrete steps to protect civilians during U.S. combat operations. Within a couple years, however, the issue came roaring back with high civilian casualties in U.S.-led efforts to dislodge Islamic State extremists from strongholds in Syria and Iraq.</p><figure class="wp-block-image size-propublica-position-large bb--size-large"><img height="766" width="1149" src="https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?w=1149" alt="A room with two empty windows filled with rubble and ash. Plaster has been knocked off areas of the brick walls, two charred beds stand in the middle of the room and two bent and broken metal carts stand nearby." class="wp-image-69966" srcset="https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg 2592w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=300,200 300w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=768,512 768w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=1024,683 1024w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=1536,1024 1536w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=2048,1365 2048w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=863,575 863w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=422,281 422w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=552,368 552w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=558,372 558w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=527,351 527w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=752,501 752w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=1149,766 1149w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=2000,1333 2000w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=400,267 400w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=800,533 800w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=1200,800 1200w, https://www.propublica.org/wp-content/uploads/2026/03/AP351079513935-1.jpg?resize=1600,1067 1600w" sizes="(max-width: 1149px) 100vw, 1149px" /><figcaption class="attribution">The aftermath of the U.S. airstrike on the Doctors Without Borders hospital in Kunduz, Afghanistan, that killed 42 people. Najim Rahim/AP Images</figcaption></figure><p>In a single week in March 2017, U.S. operations resulted in three incidents of mass civilian casualties: A <a href="https://www.cnn.com/2017/05/04/politics/syria-mosque-march-strike-us-investigation/index.html">drone attack</a> on a mosque in Syria killed around 50; <a href="https://www.hrw.org/news/2018/07/05/overdue-us-admission-civilians-were-killed-syria-strike-still-insufficient">a strike</a> in another part of Syria killed 40 in a school filled with displaced families; and bombing in the Iraqi city of Mosul led to a <a href="https://www.washingtonpost.com/news/checkpoint/wp/2017/03/25/u-s-military-acknowledges-strike-on-mosul-site-where-over-100-were-allegedly-killed/?utm_term=.817355ac37b6">building collapse</a> that killed more than 100 people taking shelter inside.</p><p>In heavy U.S. fighting to break Islamic State control over the Syrian city of Raqqa, “military leaders too often lacked a complete picture of conditions on the ground; too often waved off reports of civilian casualties; and too rarely learned any lessons from strikes gone wrong,” according to an <a href="https://www.rand.org/pubs/research_reports/RRA753-1.html#document-details">analysis</a> by the Pentagon-adjacent Rand Corp. think tank.</p><p>Under pressure from lawmakers, Trump’s then-Defense Secretary James Mattis ordered a <a href="https://www.washingtonpost.com/world/national-security/after-bloody-insurgent-wars-pentagon-launches-effort-to-prevent-civilian-deaths/2019/02/04/ce5386d8-7fec-4fcf-9cda-60e06b638115_story.html?utm_term=.6de0820930c0">review of civilian casualty protocols</a>.</p><p>Released in 2019, the review Mattis launched was seen by some <a href="https://civiliansinconflict.org/blog/pentagons-civcas-review/">advocacy groups</a> as narrow in scope but still a step in the right direction. Yet the issue soon dropped from national discourse, overshadowed by the coronavirus pandemic and landmark racial justice protests.</p><p>During the Biden administration’s chaotic withdrawal of U.S. forces from Afghanistan in August 2021, a <a href="https://www.war.gov/News/News-Stories/Article/Article/2780257/dod-august-29-strike-in-kabul-tragic-mistake-kills-10-civilians/">missile strike</a> in Kabul killed an aid worker and nine of his relatives, including seven children. Then-Defense Secretary Lloyd Austin apologized and said the department would “endeavor to learn from this horrible mistake.”</p><p>That incident, along with a New York Times <a href="https://www.nytimes.com/2021/12/19/magazine/victims-airstrikes-middle-east-civilians.html?unlocked_article_code=1.604.2IVf.CGDTPlVJ1O6j&amp;smid=url-share">investigative series</a> into deaths from U.S. airstrikes, spurred the adoption of the Civilian Harm Mitigation and Response action plan in 2022. When they established the new Civilian Protection Center of Excellence the next year, defense officials <a href="https://www.war.gov/News/Releases/Release/Article/3364914/the-department-of-defense-announces-mr-michael-mcnerney-as-director-of-the-civi/">tapped Michael McNerney</a> — the lead author of the blunt RAND report — to be its director.</p><p>“The strike against the aid worker and his family in Kabul pushed Austin to say, ‘Do it right now,’” Bryant said.</p><p>The first harm-mitigation teams were assigned to leaders in charge of some of the military’s most sensitive counterterrorism and intelligence-gathering operations: Central Command at MacDill Air Force Base in Tampa, Florida; the Joint Special Operations Command at Fort Bragg, North Carolina; and Africa Command in Stuttgart, Germany.</p><p>A former CHMR adviser who joined in 2024 after a career in international conflict work said he was reassured to find a serious campaign with a $7 million budget and deep expertise. The adviser spoke on condition of anonymity for fear of retaliation.</p><p>Only a few years before, he recalled, he’d had to plead with the Pentagon to pay attention. “It was like a back-of-the-envelope thing — the cost of a Hellfire missile and the cost of hiring people to work on this.”</p><p>Bryant became the de facto liaison between the harm-mitigation team and special operations commanders. In December, he described the experience in detail in a private briefing for aides of Sen. Chris Van Hollen, D-Md., who had sought information on civilian casualty protocols involvingboat strikes in the Caribbean Sea.</p><p>Bryant’s notes from the briefing, reviewed by ProPublica, describe an embrace of the CHMR mission by <a href="https://www.axios.com/2025/12/04/frank-bradley-admiral-drug-boat-strike">Adm. Frank Bradley,</a> who at the time was head of the Joint Special Operations Command. In October, Bradley was promoted to lead Special Operations Command.</p><p>At the end of 2024 and into early 2025, Bryant worked closely with the commander’s staff. The notes describe Bradley as “incredibly supportive” of the three-person CHMR team embedded in his command.</p><p>Bradley, Bryant wrote, directed “comprehensive lookbacks” on civilian casualties in errant strikes and used the findings to mandate changes. He also introduced training on how to integrate harm prevention and international law into operations against high-value targets. “We viewed Bradley as a model,” Bryant said.</p><p>Still, the military remained slow to offer compensation to victims and some of the new policies were difficult to independently monitor, according to a <a href="https://www.stimson.org/2025/the-perils-of-lethality/">report by the Stimson Center</a>, a foreign policy think tank. The CHMR program also faced opposition from critics who say civilian protections are already baked into laws of war and targeting protocols; the <a href="https://lieber.westpoint.edu/civilian-harm-mitigation-response-action-plan-future-battlefields/">argument</a> is that extra oversight “could have a chilling effect” on commanders’ abilities to quickly tailor operations.</p><p>To keep reforms on track, Bryant said, CHMR advisers would have to break through a culture of denial among leaders who pride themselves on precision and moral authority.</p><p>“The initial gut response of all commands,” Bryant said, “is: ‘No, we didn’t kill civilians.’”</p><p>As the Trump administration returned to the White House pledging deep cuts across the federal government, military and political leaders scrambled to preserve the Civilian Harm Mitigation and Response framework.</p><p>At first, CHMR advisers were heartened by Senate confirmation hearings where Trump’s nominees for senior defense posts affirmed support for civilian protections.</p><p>Gen. Dan Caine, chairman of the Joint Chiefs of Staff, <a href="https://www.armed-services.senate.gov/imo/media/doc/caine_apq_responses.pdf">wrote during his confirmation</a> that commanders “see positive impacts from the program.” Elbridge Colby, undersecretary of defense for policy, <a href="https://www.armed-services.senate.gov/imo/media/doc/colby_apq_responses1.pdf">wrote that</a> it’s in the national interest to “seek to reduce civilian harm to the degree possible.”</p><p>When <a href="https://www.warren.senate.gov/newsroom/press-releases/warren-secures-commitments-from-military-nominees-to-prevent-civilian-harm-study-the-long-term-effects-of-blast-overpressure">questioned about cuts</a> to the CHMR mission at a hearing last summer, U.S. Navy Vice Adm. Brad Cooper, head of Central Command, said he was committed to integrating the ideas as “part of our culture.”</p><p>Despite the <a href="https://civiliansinconflict.org/blog/us-military-voices-speak-out-in-support-of-civilian-protection/">top-level support</a>, current and former officials say, the CHMR mission didn’t stand a chance under Hegseth’s signature lethality doctrine.</p><p>The former Fox News personality, who served as an Army National Guard infantry officer in Iraq and Afghanistan, <a href="https://www.military.com/feature/2026/03/05/hegseths-stupid-rules-of-engagement-line-and-what-roe-actually-do.html">disdains rules of engagement</a> and other guardrails as constraining to the “warrior ethos.” He has <a href="https://www.newyorker.com/news/news-desk/turning-a-blind-eye-to-war-crimes">defended U.S. troops accused of war crimes</a>, including a Navy SEAL charged with stabbing an imprisoned teenage militant to death and then posing for a photo with the corpse.</p><p>A month after taking charge, Hegseth fired the military’s top judge advocate generals, known as JAGs, who provide guidance to keep operations in line with U.S. or international law. Hegseth has <a href="https://www.npr.org/2025/03/06/nx-s1-5317556/understanding-defense-secretary-hegseths-contempt-for-judge-advocate-general-officers">described the attorneys</a> as “roadblocks” and used the term “jagoff.”</p><p>At the Civilian Protection Center of Excellence, the staff tried in vain to save the program. At one point, Bryant said, he even floated the idea of renaming it the “Center for Precision Warfare” to put the mission in terms Hegseth wouldn’t consider “woke.”</p><p>By late February 2025, the CHMR mission was imploding, say current and former defense personnel.</p><p>Shortly before his job was eliminated, Bryant openly spoke out against the cuts in <a href="https://www.washingtonpost.com/national-security/2025/03/04/trump-hegseth-pentagon-firings-civilian-harm/">The Washington Post</a> and <a href="https://www.bostonglobe.com/2025/03/04/opinion/trump-hegseth-pentagon-diversity-military/">Boston Globe</a>, which he said landed him in deep trouble at the Pentagon. He was placed on leave in March, his security clearance at risk of revocation.</p><p>Bryant formally resigned in September and has since become a vocal critic of the administration’s defense policies. In columns and on TV, he warns that Hegseth’s cavalier attitude toward the rule of law and civilian protections is corroding military professionalism.</p><p>Bryant said it was hard to watch Bradley, the special operations commander and enthusiastic adopter of CHMR, <a href="https://www.pbs.org/newshour/politics/who-is-adm-bradley-lawmakers-will-hear-from-navy-admiral-who-reportedly-ordered-attack-that-killed-boat-strike-survivors">defending</a> a controversial “double-tap” on an alleged drug boat in which survivors of a first strike were killed in a follow-up hit. Legal experts have said such strikes could violate laws of warfare. Bradley did not respond to a request for comment.</p><p>“Everything else starts slipping when you have this culture of higher tolerance for civilian casualties,” Bryant said.</p><p>Concerns were renewed in early 2025 with the Trump administration’s revived counterterrorism campaign against Islamist militants regrouping in parts of Africa and the Middle East.</p><p>Last April, a U.S. air strike hit a <a href="https://www.amnesty.org/en/latest/news/2025/10/yemen-us-air-strike-on-migrant-detention-centre-must-be-investigated-as-a-war-crime/">migrant detention center</a> in northwestern Yemen, killing at least 61 African migrants and injuring dozens of others in what Amnesty International says “qualifies as an indiscriminate attack and should be investigated as a war crime.”</p><p>Operations in Somalia also have become more lethal. In 2024, Biden’s last year in office, conflict monitors recorded 21 strikes in Somalia, with a combined death toll of 189. In year one of Trump’s second term, the U.S. carried out at least 125 strikes, with reported fatalities as high as 359, according to the <a href="https://www.newamerica.org/insights/americas-counterterrorism-wars/the-war-in-somalia/">New America think tank</a>, which monitors counterterrorism operations.</p><p>“It is a strategy focused primarily on killing people,” said Alexander Palmer, a terrorism researcher at the Washington-based Center for Strategic and International Studies.</p><p>Last September, the U.S. military <a href="https://www.africom.mil/pressrelease/35996/us-forces-conduct-strikes-targeting-al-shabaab">announced an attack</a> in northeastern Somalia targeting a weapons dealer for the Islamist militia Al-Shabaab, a U.S.-designated terrorist group. On the ground, however, <a href="https://www.dropsitenews.com/p/somalia-united-states-drone-strike-killed-clan-leader">villagers said</a> the missile strike incinerated Omar Abdullahi, a respected elder nicknamed “Omar Peacemaker” for his role as a clan mediator.</p><p>After the death, the U.S. military released no details, citing operational security.</p><p>“The U.S. killed an innocent man without proof or remorse,” Abdullahi’s brother, Ali, told Somali news outlets. “He preached peace, not war. Now his blood stains our soil.”</p><p>In Iran, former personnel say, the CHMR mission could have made a difference.</p><p>Under the scrapped harm-prevention framework, they said, plans for civilian protection would’ve begun months ago, when orders to draw up a potential Iran campaign likely came down from the White House and Pentagon.</p><p>CHMR personnel across commands would immediately begin a detailed mapping of what planners call “the civilian environment,” in this case a picture of the infrastructure and movements of ordinary Iranians. They would also check and update the “no-strike list,” which names civilian targets such as schools and hospitals that are strictly off-limits.</p><p>One key question is whether the school was on the no-strike list. It sits a few yards from a naval base for the Iranian Revolutionary Guard. The building was formerly part of the base, though it has been marked on maps as a school since at least 2013, according to visual forensics investigations.</p><p>“Whoever ‘hits the button’ on a Tomahawk — they’re part of a system,” the former adviser said. “What you want is for that person to feel really confident that when they hit that button, they’re not going to hit schoolchildren.”</p><p>If the guardrails failed and the Defense Department faced a disaster like the school strike, Bryant said, CHMR advisers would’ve jumped in to help with transparent public statements and an immediate inquiry.</p><p>Instead, he called the Trump administration’s response to the attack “shameful.”</p><p>“It’s back to where we were years ago,” Bryant said. If confirmed, “this will go down as one of the most egregious failures in targeting and civilian harm-mitigation in modern U.S. history.”</p>]]></description>
      <link>https://www.propublica.org/article/trump-defense-department-iran-hegseth-civilian-casualties</link>
      <guid>https://www.propublica.org/article/trump-defense-department-iran-hegseth-civilian-casualties</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[LEGO's 0.002mm Specification and It's Implications for Manufacturing - Productivity - The Wave]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.thewave.engineer/articles.html/productivity/legos-0002mm-specification-and-its-implications-for-manufacturing-r120/</link>
      <guid>https://www.thewave.engineer/articles.html/productivity/legos-0002mm-specification-and-its-implications-for-manufacturing-r120/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Missing GitHub Status Page]]></title>
      <description><![CDATA[]]></description>
      <link>https://mrshu.github.io/github-statuses/</link>
      <guid>https://mrshu.github.io/github-statuses/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Klaus - AI Assistant Hosting]]></title>
      <description><![CDATA[]]></description>
      <link>https://klausai.com/landing-klaus</link>
      <guid>https://klausai.com/landing-klaus</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[steelbrain/ffmpeg-over-ip: Connect to remote ffmpeg servers]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto"><a href="https://ffmpeg-over-ip.com" rel="nofollow">ffmpeg-over-ip</a></h1><a id="user-content-ffmpeg-over-ip" class="anchor" aria-label="Permalink: ffmpeg-over-ip" href="#ffmpeg-over-ip"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use GPU-accelerated ffmpeg from anywhere — a Docker container, a VM, or a remote machine — without GPU passthrough or shared filesystems.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">The Problem</h2><a id="user-content-the-problem" class="anchor" aria-label="Permalink: The Problem" href="#the-problem"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">GPU transcoding is powerful, but getting access to the GPU is painful:</p>
<ul dir="auto">
<li><strong>Docker containers</strong> need <code>--runtime=nvidia</code>, device mounts, and driver version alignment between host and container</li>
<li><strong>Virtual machines</strong> need PCIe passthrough or SR-IOV — complex setup that locks the GPU to one VM</li>
<li><strong>Remote machines</strong> need shared filesystems (NFS/SMB) with all the path mapping, mount maintenance, and permission headaches that come with them</li>
</ul>
<p dir="auto">You just want your media server to use the GPU for transcoding. You shouldn't need to restructure your infrastructure to make that happen.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">The Solution</h2><a id="user-content-the-solution" class="anchor" aria-label="Permalink: The Solution" href="#the-solution"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Run the ffmpeg-over-ip server on the host (or any machine with a GPU). Point your app at the client binary instead of ffmpeg. Done — your app gets GPU-accelerated transcoding without needing direct GPU access.</p>
<p dir="auto">The client pretends to be ffmpeg. It forwards arguments to the server, which runs a patched ffmpeg that tunnels all file I/O back through the connection. Files are never stored on the server.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CLIENT (has files, no GPU)              SERVER (has GPU)
========================              ===========================

Media server invokes &quot;ffmpeg&quot;         Daemon listening on :5050
        |                                      |
  ffmpeg-over-ip-client               ffmpeg-over-ip-server
        |                                      |
        +--------- TCP connection ------------&gt;+
        |                                      |
  Local filesystem                      patched ffmpeg
  (real files)                    (file I/O tunneled back to client)"><pre class="notranslate"><code>CLIENT (has files, no GPU)              SERVER (has GPU)
========================              ===========================

Media server invokes "ffmpeg"         Daemon listening on :5050
        |                                      |
  ffmpeg-over-ip-client               ffmpeg-over-ip-server
        |                                      |
        +--------- TCP connection ------------&gt;+
        |                                      |
  Local filesystem                      patched ffmpeg
  (real files)                    (file I/O tunneled back to client)
</code></pre></div>
<p dir="auto">No GPU passthrough. No shared filesystem. No NFS. No SMB. Just one TCP port.</p>
<p dir="auto">Releases include pre-built ffmpeg and ffprobe binaries with broad hardware acceleration support (NVENC, QSV, VAAPI, AMF, VideoToolbox, and more) — built on the <a href="https://github.com/jellyfin/jellyfin-ffmpeg">jellyfin-ffmpeg</a> pipeline. No need to install ffmpeg separately on either side.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Quick Start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick Start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="docs/quick-start.md">docs/quick-start.md</a> to get up and running in a few minutes.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Upgrading from v4</h2><a id="user-content-upgrading-from-v4" class="anchor" aria-label="Permalink: Upgrading from v4" href="#upgrading-from-v4"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="docs/upgrading.md">docs/upgrading.md</a> for migration guide and breaking changes.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Configuration</h2><a id="user-content-configuration" class="anchor" aria-label="Permalink: Configuration" href="#configuration"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="docs/configuration.md">docs/configuration.md</a> for full configuration reference (config file search paths, server/client options, rewrites, logging, address formats).</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Docker</h2><a id="user-content-docker" class="anchor" aria-label="Permalink: Docker" href="#docker"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="docs/docker.md">docs/docker.md</a> for Docker integration, Unix socket setup, and debugging tips.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">How It Works</h2><a id="user-content-how-it-works" class="anchor" aria-label="Permalink: How It Works" href="#how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>Your media server calls <code>ffmpeg-over-ip-client</code> with normal ffmpeg arguments</li>
<li>The client connects to the server and sends the command with HMAC authentication</li>
<li>The server launches its patched ffmpeg, which tunnels all file reads and writes back to the client</li>
<li>stdout/stderr are forwarded in real-time; when ffmpeg exits, the client exits with the same code</li>
</ol>
<p dir="auto">Multiple clients can connect to the same server simultaneously — each session gets its own ffmpeg process.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Supported Platforms</h2><a id="user-content-supported-platforms" class="anchor" aria-label="Permalink: Supported Platforms" href="#supported-platforms"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th>Client</th>
<th>Server + ffmpeg</th>
</tr>
</thead>
<tbody>
<tr>
<td>Linux x86_64</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>Linux arm64</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>macOS arm64</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>macOS x86_64</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>Windows x86_64</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Troubleshooting</h2><a id="user-content-troubleshooting" class="anchor" aria-label="Permalink: Troubleshooting" href="#troubleshooting"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="docs/troubleshooting.md">docs/troubleshooting.md</a> for common issues and debugging tips.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Building from Source</h2><a id="user-content-building-from-source" class="anchor" aria-label="Permalink: Building from Source" href="#building-from-source"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="CONTRIBUTING.md">CONTRIBUTING.md</a> for build instructions, running tests, and project structure.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Security</h2><a id="user-content-security" class="anchor" aria-label="Permalink: Security" href="#security"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Authentication</strong>: HMAC-SHA256 with a shared secret. Every command is signed.</li>
<li><strong>Single port</strong>: Only the server listens on a port. The client makes outbound connections only.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Split license — see <a href="LICENSE.md">LICENSE.md</a>. The fio layer and ffmpeg patches (<code>fio/</code>, <code>patches/</code>) are GPL v3 (derived from ffmpeg). Everything else is MIT.</p>
</article></div>]]></description>
      <link>https://github.com/steelbrain/ffmpeg-over-ip</link>
      <guid>https://github.com/steelbrain/ffmpeg-over-ip</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Shape of Paris]]></title>
      <description><![CDATA[<p>posted  by <a href="http://www.kottke.org">Jason Kottke</a>  ·  gift link</p><p><a href="https://www.youtube.com/watch?v=4q8wZ15ALz4">The Shape of Paris</a> is a balletic short film of skateboarder <a href="https://www.instagram.com/authenticandyanderson/">Andy Anderson</a> zooming, grinding, spinning, and floating around Paris in the summertime. It is also beautifully shot by <a href="https://brettnovak.com/">Brett Novak</a>; Paris has never looked better. As a YT commenter put it: “bro wtf this is the cleanest footage I’ve ever seen. The cinematography and color grading is insane.”</p><p>Also, this is the first skate video I’ve seen with “trick acknowledgements” in the credits. Great touch. (via <a href="https://craigmod.com/">craig mod</a>)</p>]]></description>
      <link>https://kottke.org/26/03/the-shape-of-paris</link>
      <guid>https://kottke.org/26/03/the-shape-of-paris</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Adactio: Journal—A web font strategy]]></title>
      <description><![CDATA[<p><a href="https://thesession.org/">The Session</a> has been online in some form since the late 1990s. That’s long before web fonts existed.</p><p>To begin with, Times New Roman was the only game in town if you wanted serif type on a website. When Microsoft introduced Georgia it was a godsend. A beautiful typeface designed by <a href="https://en.wikipedia.org/wiki/Matthew_Carter">Matthew Carter</a> for the screen. I put it right at the start of my font stack for The Session.</p>
<p>Later, web fonts came along. Boy, does that short sentence belie the drama! There were <em>very</em> heated discussions about whether web browsers should provide this ability at all, and what it would mean for type foundries.</p>
<p>Microsoft led the way with their prorietary EOT format. Then everyone agreed on WOFF. Finally we got WOFF2, Electric Boogaloo.</p>
<p>Perhaps more important than that, we got intermediaries. Typekit, Fontdeck, and then the big daddy, <a href="https://fonts.google.com/">Google Fonts</a>.</p>
<p>That’s pretty much the state of play today. Oh yeah, and we’ve got variable fonts now.</p>
<p>I remember Nick Sherman presenting the idea of variable fonts at an <a href="https://2015.ampersandconf.com/">Ampersand</a> event years ago. I remember thinking “great idea, but it’ll never happen.” Pure science fiction. I thought the same thing when I first saw a conference presentation about a miraculous image format called Scalable Vector Graphics.</p>
<p>Sometimes I like to stop and take stock of what we take for granted in web browsers now. Web fonts. Variable web fonts. SVG. Flexbox. Grid. Media queries. Container queries. Fluid typography. And I haven’t even mentioned how we were once limited to just 216 colours on the web.</p>
<h3>Georgia</h3>
<p>Given all the advances in web typography, you might be wondering how my font strategy for The Session changed over the years.</p>
<p>It didn’t.</p>
<p>I mean, sure, I added fluid typography. That was a natural extension of my love for liquid layouts and, later, responsive design. But the font stack itself? That was still Georgia all the way.</p>
<p>Y’see, performance has always been a top priority for The Session. If I was going to replace a system font with a web font that the user had to download, it really needed to be worth it.</p>
<p>Over the years I dabbled with different typefaces but none of them felt quite right to me. And I still think Georgia is a beautiful typeface.</p>
<p>“But your website will look like lots of other websites!” some may cry. That used to be true when all we had was system fonts. But now that web fonts have become the norm, it’s actually pretty unusual to see Georgia in the wild.</p>
<h3>Lora</h3>
<p>Recently I found a font I liked. Part of why I like it is that it shares a lot of qualities with Georgia. It’s <a href="https://www.cyreal.org/fonts/lora/">Lora</a> by Olga Karpushina and Alexei Vanyashin.</p>
<p>I started to dabble with it and began seriously contemplating using it on The Session.</p>
<p>It’s a variable font, which is great. But actually, I’m not using that many weights on The Session. I could potentially just use a non-variable variety. It comes in fixed weights of regular, medium, semibold, and bold.</p>
<p>Alas, the regular weight (400) is a bit too light and the medium weight (500) is a bit too heavy. My goldilocks font weight is more like 450.</p>
<p>Okay, so the variable font it is. That also allows me to play around with some subtle variations in weights. As the font size gets bigger for headings, the font weight can reduce ever so slightly. And I can adjust the overall font weight down in dark mode (there’s no grading feature in this font, alas).</p>
<h3>Subsetting</h3>
<p>Lora supports a lot of alphabets, which is great—quite a few alphabets turn up on The Session occasionally. But this means that the font file size is quite large. 84K.</p>
<p><a href="https://fontsubset.com/">Subsetting</a> to the rescue!</p>
<p>I created a subset of Lora that has everything except Cyrillic, Greek, and Latin Extended-B. I created another subset that <em>only</em> has Cyrillic, Greek, and Latin Extended-B. Now I’ve got two separate font files that are 48K and 41K in size.</p>
<p>I wrote two <code>@font-face</code> declarations for the two files. They’ve got the same <code>font-family</code> (Lora), the same <code>font-weight</code> (400 700), and the same <code>font-style</code> (normal) but they’ve got different values for <code>unicode-range</code>. That way, browsers know to only use appropriate file when characters on the page actually match the unicode range.</p>
<p>The first file is definitely going to be used. The second one might not even be needed on most pages.</p>
<p>I want to prioritise the loading of that first subsetted font file so it gets referenced in a <code>link</code> element with <code>rel="preload"</code>.</p>
<h3>The switcheroo</h3>
<p>As well as file size, my other concern was how the swapping from Georgia to Lora would be perceived, especially on a slow connection. I wanted to avoid any visible rejiggering of the content.</p>
<p>This is where <code>size-adjust</code> comes in, along with its compadres <code>ascent-override</code> and <code>descent-override</code>.</p>
<p>Rather than adjusting the default size of Lora to match that of Georgia, I want to do it the other way around; adjust the fallback font to match the web font.</p>
<p>Here’s how I’m doing it:</p>
<pre>
@font-face {
    font-family: 'Fallback for Lora';
    src: local('Georgia');
    size-adjust: 105.77%;
    ascent-override: 95.11%;
    descent-override: 25.9%;
}
</pre>
<p>And then my font stack is:</p>
<pre>font-family: Lora, 'Fallback for Lora', Georgia, serif;
</pre>
<p>It’s highly unlikely that any device out there has a system font called “Fallback for Lora” so I can be pretty confident that the <code>@font-face</code> adjustment rules will only get applied to browsers that have the right local font, Georgia.</p>
<p>But where did those magic numbers come from for <code>size-adjust</code>, <code>ascent-override</code>, and <code>descent-override</code>?</p>
<p>They came from <a href="https://developer.chrome.com/blog/font-fallbacks/">Katie Hempenius</a>. As well as maintaing <a href="https://github.com/khempenius/font-fallbacks-dataset">a repo of font metrics</a>, she provides <a href="https://developer.chrome.com/blog/font-fallbacks/#calculating_size-adjust_and_font_metric_overrides">the formula</a> needed to calculate all three values. Or you could use <a href="https://screenspan.net/fallback">this handy tool</a> to eyeball it.</p>
<p>With that, Georgia gets swapped out for Lora with a minimum of layout shift.</p>
<h3>First-timers and repeat visitors</h3>
<p>Even with the layout shift taken care of, do I want to serve up web fonts to someone on a slow connection?</p>
<p>It depends. Specifically, it depends on whether it’s their first time visiting.</p>
<p>The Session already treats first time visitors differently to repeat visitors. The first time you visit the site, critical CSS is embedded in the <code>head</code> of the HTML page instead of being referenced in an external style sheet. Only once the page has loaded does the full style sheet also get downloaded and cached.</p>
<p>I decided that my <code>@font-face</code> rules pointing to the web fonts are <em>not</em> critical CSS. If it’s your first time visiting, those CSS rules only get downloaded after the page is done loading.</p>
<p>And unless you’re on a fast connection, you won’t see Georgia get swapped out for Lora. That’s because I’ve gone with a <code>font-display</code> value of “optional”.</p>
<p>Most people use “swap”. Some people use “fallback”. You’ve got to be pretty hardcore to use “optional”.</p>
<p>But the <em>next</em> page you go to, or the next time you come to the site, you more than likely <em>will</em> see Lora straight away. That’s because of the service worker I’ve got quietly putting static assets into the Cache API: CSS, JavaScript, and now web fonts.</p>
<p>So even though I’m prioritising snappy performance over visual consistency, it’s a trade-off that only really comes into play for first visits.</p>
<h3>Next</h3>
<p>I’m pretty happy with the overall strategy. Still, I’m not going to just set it and forget it. I’ll be monitoring <a href="https://calibreapp.com/tools/core-web-vitals-test/thesession.org">the CRUX data for The Session</a> keeping a particular eye on cumulative layout shift.</p>
<p>Before adding web fonts, the cumulative layout shift on <a href="https://thesession.org/">The Session</a> was zero. I <em>think</em> I’ve taken all the necessary steps to keep it nice and low, but if I’m wrong I’ll need to revisit my strategy.</p>
<p><strong>Update</strong>: Big thanks to <a href="https://pixelambacht.nl/">Roel Nieskens</a>—of <a href="https://wakamaifondue.com/">Wakamai Fondue</a> fame—who managed to get the file size of my main subsetted font down even further; bedankt!</p>]]></description>
      <link>https://adactio.com/journal/22450</link>
      <guid>https://adactio.com/journal/22450</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Revealed: UK’s multibillion AI drive is built on ‘phantom investments’]]></title>
      <description><![CDATA[<p class="dcr-130mj7b">A multibillion-pound drive to "mainline AI into the veins" of the British economy is riddled with "phantom investments" and shaky accounting, a Guardian investigation has found.</p><p class="dcr-130mj7b">Since 2024, successive Conservative and Labour governments have proclaimed massive deals to build new datacentres, create thousands of jobs and construct a supercomputer.</p><p class="dcr-130mj7b">The investments – led by two firms linked to AI giant Nvidia - have been touted as a cornerstone of the government's promise to use tech to turbocharge the economy.</p><p class="dcr-130mj7b">On Monday, former UK deputy prime minister Sir Nick Clegg and former Meta chief operating officer Sheryl Sandberg were announced as new board members at one of the firms, NScale. Nscale also said it had raised a $2bn funding round, sending its valuation soaring to $14.6bn.</p><p class="dcr-130mj7b">But a Guardian investigation has shown the money isn't necessarily real, the datacentres may not be new, the jobs are unaccounted for – and the supercomputer site 12 miles north of London is still a scaffolding yard.</p><figure id="071f7ffe-8e8d-43e8-9c23-44611943d0b7" data-spacefinder-role="inline" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="dcr-173mewl"><div class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="The Alandale scaffolding yard in Loughton, Essex." src="https://i.guim.co.uk/img/media/273d15705573a263792bd1db6c20955fb745ade2/0_0_6960_4640/master/6960.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="296.66666666666663" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">When asked about a series of claimed investments, the UK's Department for Science, Innovation and Technology declined to answer detailed questions but said it "rejected these assertions".</p><p class="dcr-130mj7b">A statement added: "Our AI sector has attracted more than £100bn in private investment since the government took office, with our AI sector growing 23 times faster than the wider economy last year. That is delivering the jobs and opportunities hardworking people deserve."</p><p class="dcr-130mj7b">But it also acknowledged limitations to its oversight.</p><p class="dcr-130mj7b">In one case, it said that there was no contract in place for a £1.9bn ($2.5bn) investment despite a press release declaring that one had been signed. In another, it said that it was "not playing an active role in auditing these commitments".</p><p class="dcr-130mj7b">The findings raise questions about a series of massive AI investments announced globally in the past year, many in high-level press releases from governments and tech companies.</p><p class="dcr-130mj7b">With over £500bn promised in 2025, countries worldwide are seeking to conjure economic growth from AI's transformative potential.</p><p class="dcr-130mj7b">Last year, the UK prime minister, Keir Starmer, <a href="https://news.sky.com/story/uk-to-mainline-ai-in-the-veins-under-new-plans-from-sir-keir-starmer-13287743" data-link-name="in body link">said that</a> if AI were "fully embraced", it could bring £47bn to the economy each year – and promised to "<a href="https://www.theguardian.com/politics/2025/jan/12/mainlined-into-uks-veins-labour-announces-huge-public-rollout-of-ai" data-link-name="in body link">mainline AI</a> into the veins of the UK".</p><figure id="061f3a24-706b-4894-a192-06d33fb034d9" data-spacefinder-role="inline" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="dcr-173mewl"><div class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="Starmer speaking at a podium with a sign reading 'Plan for change'" src="https://i.guim.co.uk/img/media/59bad094a5caeac18b6d5961a32e61e7fa5107b6/0_0_4848_3232/master/4848.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="296.66666666666663" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">But the UK example will raise fears that, without oversight, the value of these investments may simply enrich companies and investors that are largely headquartered in the US.</p><p class="dcr-130mj7b">"These are phantom investments," said Cecilia Rikap, a professor of economics at University College London, who said similar things were happening around the world.</p><p class="dcr-130mj7b">"Big tech companies artificially inflate datacentres' job creation and economic impact to please governments like the British one, which are desperate to claim they are making the economy grow."</p><h2 id="the-rules-are-very-flexible" class="dcr-12ibh7f">'The rules are very flexible'</h2><p class="dcr-130mj7b">The UK government's AI plans centre on two companies backed by the $4tn tech giant Nvidia: London-based Nscale and the US company CoreWeave.</p><p class="dcr-130mj7b">In 2024, Rishi Sunak's government hailed one of the first AI investments in Britain, a £1bn commitment from CoreWeave to help "cement the UK's position as a world leader in AI."</p><figure id="58a78173-c635-4ca2-9b0b-e83f3ecefc08" data-spacefinder-role="inline" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="dcr-173mewl"><div class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="Sunak in front of a UK flag, wearing a poppy" src="https://i.guim.co.uk/img/media/606c7e9d3db57d41b932550f230944eae4f28117/0_0_6000_4000/master/6000.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="296.66666666666663" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">CoreWeave's press release said it would invest £1bn in the UK, and quoted the then technology secretary, Michelle Donelan, as saying this would bring "two new datacentres to our shores."</p><p class="dcr-130mj7b">CoreWeave said the investment would "create job opportunities" and herald further expansion. Six months later, it announced that the two datacentres were operational: one in London Docklands, and one in Crawley near Gatwick.</p><p class="dcr-130mj7b">Planning records indicate that CoreWeave built no new datacentres at either location during that time period. Neither did the two partners mentioned in its press release.</p><p class="dcr-130mj7b">In fact, while CoreWeave's – and the government's – communications imply that physical buildings were built by suggesting the investment would bring <a href="https://investors.coreweave.com/news/news-details/2024/CoreWeave-Invests-1-Billion-in-UK-Opens-New-European-Headquarters-and-Data-Centres-in-London-to-Bring-Cloud-Infrastructure-to-Power-the-AI-Revolution/default.aspx" data-link-name="in body link">"two new data centres to our shores"</a>, this was misleading.</p><figure id="f3304de7-abbf-4296-8d63-ab9349aab3e6" data-spacefinder-role="supporting" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="dcr-a2pvoh"><div id="img-5" class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=380&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 1300px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 1300px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=380&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 1300px)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=300&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 980px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 980px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=300&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 980px)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="Michael Intrator, co-founder and chief executive of CoreWeave, speaking in New York in February." src="https://i.guim.co.uk/img/media/624e4f192958923c510675dcb72e4c2164b53fc2/0_0_2741_3427/master/2741.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="556.3717621306092" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">The Guardian understands that CoreWeave became a customer of two existing datacentres, one built in 2002 and one built in 2015, both of which lease space to a host of other companies, including Google and Fujitsu. CoreWeave rented space in these datacentres, and deployed Nvidia chips that it had paid for.</p><p class="dcr-130mj7b">Effectively, its investment amounts to the relocation into the UK of computer chips manufactured in Taiwan by a US company.</p><p class="dcr-130mj7b">There is no indication in public-facing materials that CoreWeave has made other investments, beyond renting an office in a building in Southwark, London, which it has called its "European headquarters."</p><p class="dcr-130mj7b">Rikap said it was "very common" for datacentre developers to frame the purchase of equipment, or the acquisition of other companies, as investment. "The rules are very flexible and help them to make these big claims and investments that a government like Starmer's, which is desperate for good news, can use for their favour."</p><p class="dcr-130mj7b">In a response to a query from the Guardian, the government said that the figures it had announced for CoreWeave's investment did not come from them. Astatement said they were produced by CoreWeave.</p><p class="dcr-130mj7b">It did not say whether this investment amounted to capital or equipment.</p><p class="dcr-130mj7b">CoreWeave said that bringing new datacentre capacity online by deploying chips within an existing site was an "industry-standard" approach. The deployment of these chips, the associated lease and power costs, the opening of its office and personnel costs represented the whole of the £1bn investment, it said.</p><p class="dcr-130mj7b">"Our investments are designed to expand compute capacity, and enable AI adoption and innovation across enterprises, research institutions, the public sector and startups. We are delivering advanced, purpose-built AI infrastructure to support the development of AI at scale," the company said. It refused to say how many jobs had been created.</p><p class="dcr-130mj7b">Nscale's flagship project was announced in January 2025, when the government said that the company would build a supercomputer site on the outskirts of Loughton in east London, a project dubbed "the largest UK sovereign AI datacentre." This was reported to be part of a $2.5bn investment the company was making into the UK.</p><p class="dcr-130mj7b">That <a href="https://www.gov.uk/government/news/prime-minister-sets-out-blueprint-to-turbocharge-ai" data-link-name="in body link">press release</a> said that Nscale had "signed a contract" to complete this datacentre by 2026.</p><p class="dcr-130mj7b">Nscale's own press release from the time said that it "confirmed" its investment in the UK by buying the site in Loughton, and the supercomputer was to be "live" by Q4 2026.</p><p class="dcr-130mj7b">But the proposed site, in an industrial park on the outskirts of Loughton, was still being used as a scaffolding yard by a London-based company when the Guardian visited in February.</p><figure id="e9662007-c1eb-45b4-9500-418727bafd54" data-spacefinder-role="inline" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="dcr-173mewl"><div id="img-6" class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="Scaffolding yard photographed from behind fence" src="https://i.guim.co.uk/img/media/d02219227dc75466c169d6cdd486e3dd82e14d6f/0_0_6960_4640/master/6960.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="296.66666666666663" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">Nscale submitted a planning application to build there at the end of February, after the Guardian had begun to make inquiries. Land records appear to indicate that Nscale has not yet been registered as owner of the site. Nscale could not say whether the company owned the land, and could not give a date on which any purchase had occurred.</p><p class="dcr-130mj7b">In response to a query from the Guardian, the government said that the figure Nscale had given for its investment in the UK, $2.5bn, was from Nscale itself.</p><p class="dcr-130mj7b">Asked about the terms of the contract that Nscale had signed to build the supercomputer by the end of this year, the government did not reply directly. Instead, it said that Nscale's entire $2.5bn investment was "not a formal contract, rather an intention to commit capital", and "may well include equipment and capital funding".</p><p class="dcr-130mj7b">Nscale's accounts for 2025 are overdue, but do not yet show any commitment to investments in the UK.</p><p class="dcr-130mj7b">An Nscale spokesperson said: "As a UK-headquarted company, we remain committed to the UK investment we announced – with the Loughton project in support of Microsoft progressing as we envisaged. We're investing not only in the site itself but also in offsite power infrastructure, local contractors and local suppliers."</p><h2 id="the-claims-are-pie-in-the-sky" class="dcr-12ibh7f">'The claims are pie-in-the-sky'</h2><p class="dcr-130mj7b">Nscale and CoreWeave are committed to further projects.</p><p class="dcr-130mj7b">Nscale, along with Microsoft and the ChatGPT developer, OpenAI, are <a href="https://www.gov.uk/government/news/us-uk-pact-will-boost-advances-in-drug-discovery-create-tens-of-thousands-of-jobs-and-transform-lives" data-link-name="in body link">to establish Stargate UK</a>, a "critical" project to help develop the UK's own AI facilities on sites across the country.</p><p class="dcr-130mj7b">In response to a query from the Guardian, the government said that this project was also a part of Nscale's $2.5bn investment. It did not give a breakdown of the total amount, and said it did not have a mechanism in place to review it.</p><p class="dcr-130mj7b">"Government will continue to work closely with Nscale in securing this investment into UK, however, it is not playing an active role in auditing these commitments," said a spokesperson for the Department for Science, Innovation and Technology.</p><figure id="60fefc66-e1af-44cc-9123-597df21c4f93" data-spacefinder-role="inline" data-spacefinder-type="model.dotcomrendering.pageElements.ImageBlockElement" class="dcr-173mewl"><div id="img-7" class="dcr-1t8m8f2"><picture class="dcr-evn1e9"><source srcset="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=620&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 660px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 660px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=620&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 660px)" /><source srcset="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=605&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 480px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 480px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=605&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 480px)" /><source srcset="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=445&amp;dpr=2&amp;s=none&amp;crop=none" media="(min-width: 320px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: 320px) and (min-resolution: 120dpi)" /><source srcset="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" media="(min-width: 320px)" /><img alt="A datacentre in Northern Sweden." src="https://i.guim.co.uk/img/media/e0e002b894da13966981f7bca1b8529b6db24838/0_0_5760_3636/master/5760.jpg?width=445&amp;dpr=1&amp;s=none&amp;crop=none" width="445" height="280.90625" class="dcr-evn1e9" /></picture></div></figure><p class="dcr-130mj7b">CoreWeave, meanwhile, is to back an AI growth zone in Lanarkshire, which the government has said will be completed within four years and bring the company's investment into UK infrastructure to £2.5bn. That development is a "key pillar" of the government's industrial strategy. The government says the project will create 3,400 jobs in the construction of the facility; CoreWeave's partner, DataVita, has promised more than 1GW of onsite renewable energy, the energy equivalent of the output of a nuclear power station.</p><p class="dcr-130mj7b">The Lanarkshire site currently hosts a datacentre with 24MW of electricity – less than 3% of the promised renewable supply – operated by the Scottish firm DataVita, which is partnering with CoreWeave in developing the site. One planning application, to extend this to 40MW, has been approved; other applications, including for a larger site, cannot be filed until April, according to the planning portal of the local council.</p><p class="dcr-130mj7b">"This hyperscale datacentre would have the energy demand of half a million homes, an eighth of the entire Scottish electricity demand," said Dr Kat Jones, director of the Scottish countryside charity APRS, who has been researching the growth of hyperscale and AI datacentres across Scotland.</p><p class="dcr-130mj7b">She said that the claimed plans for 1GW of on-site renewable energy "are total pie-in-the-sky. Where is this going to come from?"</p><p class="dcr-130mj7b">In the press release announcing the site, the government said that CoreWeave's commitment to the site was part of a package of investments the company "has made to AI projects in the UK."</p><p class="dcr-130mj7b">In response to a query from the Guardian, the Department for Science, Innovation and Technology would not say if it had audited this commitment, or how – or if any of the investment had been received. Questions on the form of the investment, it said, were "ultimately" up to CoreWeave.</p><p class="dcr-130mj7b">"The details of the Lanarkshire commitment are subject to DataVita and CoreWeave," it said.</p><p class="dcr-130mj7b">Asked about the Lanarkshire site, CoreWeave said that questions about its power usage should be directed to DataVita, its partner, and that the project "remains on schedule, with the first phase expected to come online later this year."</p><p class="dcr-130mj7b">DataVita did not respond to a request for comment on this piece.</p><p class="dcr-130mj7b">Asked about the 3,400 jobs, CoreWeave said: "Any job projections that have been shared in relation to these UK datacentre efforts have originated from the UK Government and DataVita, not CoreWeave."</p><p class="dcr-130mj7b">A government spokesperson said: "Datacentres are vital to delivering the benefits of AI, from boosting productivity to improving public services. We have a clear plan to deliver the infrastructure the UK needs and get it connected, and make no apologies for working with leading global firms to invest in and build datacentres here."</p><p class="dcr-130mj7b"><em>Additional reporting: Dan Milmo and Libby Brooks</em></p>]]></description>
      <link>https://www.theguardian.com/technology/2026/mar/09/revealed-uks-multibillion-ai-drive-is-built-on-phantom-investments</link>
      <guid>https://www.theguardian.com/technology/2026/mar/09/revealed-uks-multibillion-ai-drive-is-built-on-phantom-investments</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[European Tech Map - European Tech Alternatives | GDPR Compliant Software]]></title>
      <description><![CDATA[<p>Find GDPR-compliant, EU-hosted software and service alternatives that respect your data sovereignty. Browse 500+ European companies across 30+ categories.</p><section><h2>Popular Categories</h2><ul><li><a href="https://europeantechmap.eu/category/cloud-computing">Cloud Computing</a></li>
<li><a href="https://europeantechmap.eu/category/crm">CRM</a></li>
<li><a href="https://europeantechmap.eu/category/cybersecurity">Cybersecurity</a></li>
<li><a href="https://europeantechmap.eu/category/analytics">Analytics</a></li>
<li><a href="https://europeantechmap.eu/category/email">Email</a></li>
<li><a href="https://europeantechmap.eu/category/cloud-storage">Cloud Storage</a></li>
<li><a href="https://europeantechmap.eu/category/communication">Communication</a></li>
<li><a href="https://europeantechmap.eu/category/project-management">Project Management</a></li>
<li><a href="https://europeantechmap.eu/category/e-commerce">E-commerce</a></li>
<li><a href="https://europeantechmap.eu/category/ai-machine-learning">AI &amp; Machine Learning</a></li>
<li><a href="https://europeantechmap.eu/category/document-collaboration">Document Collaboration</a></li>
<li><a href="https://europeantechmap.eu/category/identity-access">Identity &amp; Access</a></li>
</ul></section><section><h2>Popular Alternatives</h2><ul><li><a href="https://europeantechmap.eu/alternative-to/google-analytics">Google Analytics Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/amazon-web-services">AWS Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/salesforce">Salesforce Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/slack">Slack Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/microsoft-365">Microsoft 365 Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/zoom">Zoom Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/dropbox">Dropbox Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/mailchimp">Mailchimp Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/hubspot">HubSpot Alternatives</a></li>
<li><a href="https://europeantechmap.eu/alternative-to/jira">Jira Alternatives</a></li>
</ul></section><section><h2>Browse by Country</h2><ul><li><a href="https://europeantechmap.eu/country/germany">Germany</a></li>
<li><a href="https://europeantechmap.eu/country/france">France</a></li>
<li><a href="https://europeantechmap.eu/country/netherlands">Netherlands</a></li>
<li><a href="https://europeantechmap.eu/country/sweden">Sweden</a></li>
<li><a href="https://europeantechmap.eu/country/finland">Finland</a></li>
<li><a href="https://europeantechmap.eu/country/spain">Spain</a></li>
<li><a href="https://europeantechmap.eu/country/ireland">Ireland</a></li>
<li><a href="https://europeantechmap.eu/country/austria">Austria</a></li>
<li><a href="https://europeantechmap.eu/country/switzerland">Switzerland</a></li>
<li><a href="https://europeantechmap.eu/country/denmark">Denmark</a></li>
<li><a href="https://europeantechmap.eu/country/poland">Poland</a></li>
<li><a href="https://europeantechmap.eu/country/italy">Italy</a></li>
</ul></section><section><h2>About European Tech Map</h2><p>European Tech Map is the leading directory of European software companies and GDPR-compliant alternatives. We help businesses find trustworthy, privacy-respecting technology solutions hosted in Europe.</p><ul><li><a href="https://europeantechmap.eu/about">About Us</a></li>
<li><a href="https://europeantechmap.eu/faq">FAQ</a></li>
<li><a href="https://europeantechmap.eu/pricing">Pricing</a></li>
<li><a href="https://europeantechmap.eu/contact">Contact</a></li>
<li><a href="https://europeantechmap.eu/privacy">Privacy Policy</a></li>
<li><a href="https://europeantechmap.eu/terms">Terms of Service</a></li>
<li><a href="https://europeantechmap.eu/imprint">Imprint</a></li>
</ul></section>]]></description>
      <link>https://europeantechmap.eu/</link>
      <guid>https://europeantechmap.eu/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[msitarzewski/agency-agents: A complete AI agency at your fingertips** - From frontend wizards to Reddit community ninjas, from whimsy injectors to reality checkers. Each agent is a specialized expert with personality, processes, and proven deliverables.]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">🎭 The Agency: AI Specialists Ready to Transform Your Workflow</h1><a id="user-content--the-agency-ai-specialists-ready-to-transform-your-workflow" class="anchor" aria-label="Permalink: 🎭 The Agency: AI Specialists Ready to Transform Your Workflow" href="#-the-agency-ai-specialists-ready-to-transform-your-workflow"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<blockquote>
<p dir="auto"><strong>A complete AI agency at your fingertips</strong> - From frontend wizards to Reddit community ninjas, from whimsy injectors to reality checkers. Each agent is a specialized expert with personality, processes, and proven deliverables.</p>
</blockquote>
<p dir="auto"><a href="https://github.com/msitarzewski/agency-agents"><img src="https://camo.githubusercontent.com/1bdae7a86b6ca2d1bc969d929a6dc4283a746aa96799f9fab75fce7bfed32560/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6d73697461727a6577736b692f6167656e63792d6167656e74733f7374796c653d736f6369616c" alt="GitHub stars" data-canonical-src="https://img.shields.io/github/stars/msitarzewski/agency-agents?style=social" style="max-width: 100%;"></a>
<a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT" data-canonical-src="https://img.shields.io/badge/License-MIT-yellow.svg" style="max-width: 100%;"></a>
<a href="https://makeapullrequest.com" rel="nofollow"><img src="https://camo.githubusercontent.com/dd0b24c1e6776719edb2c273548a510d6490d8d25269a043dfabbd38419905da/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e737667" alt="PRs Welcome" data-canonical-src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" style="max-width: 100%;"></a>
<a href="https://github.com/sponsors/msitarzewski"><img src="https://camo.githubusercontent.com/856bf8030a60ef09cec6b0ccacae765ece8eef592b2642a33dcfec11fb623e49/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53706f6e736f722d2545322539442541342d70696e6b3f6c6f676f3d676974687562" alt="Sponsor" data-canonical-src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-pink?logo=github" style="max-width: 100%;"></a></p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🚀 What Is This?</h2><a id="user-content--what-is-this" class="anchor" aria-label="Permalink: 🚀 What Is This?" href="#-what-is-this"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Born from a Reddit thread and months of iteration, <strong>The Agency</strong> is a growing collection of meticulously crafted AI agent personalities. Each agent is:</p>
<ul dir="auto">
<li><strong>🎯 Specialized</strong>: Deep expertise in their domain (not generic prompt templates)</li>
<li><strong>🧠 Personality-Driven</strong>: Unique voice, communication style, and approach</li>
<li><strong>📋 Deliverable-Focused</strong>: Real code, processes, and measurable outcomes</li>
<li><strong>✅ Production-Ready</strong>: Battle-tested workflows and success metrics</li>
</ul>
<p dir="auto"><strong>Think of it as</strong>: Assembling your dream team, except they're AI specialists who never sleep, never complain, and always deliver.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">⚡ Quick Start</h2><a id="user-content--quick-start" class="anchor" aria-label="Permalink: ⚡ Quick Start" href="#-quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Option 1: Use with Claude Code (Recommended)</h3><a id="user-content-option-1-use-with-claude-code-recommended" class="anchor" aria-label="Permalink: Option 1: Use with Claude Code (Recommended)" href="#option-1-use-with-claude-code-recommended"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Copy agents to your Claude Code directory
cp -r agency-agents/* ~/.claude/agents/

# Now activate any agent in your Claude Code sessions:
# &quot;Hey Claude, activate Frontend Developer mode and help me build a React component&quot;"><pre><span class="pl-c"><span class="pl-c">#</span> Copy agents to your Claude Code directory</span>
cp -r agency-agents/<span class="pl-k">*</span> <span class="pl-k">~</span>/.claude/agents/

<span class="pl-c"><span class="pl-c">#</span> Now activate any agent in your Claude Code sessions:</span>
<span class="pl-c"><span class="pl-c">#</span> "Hey Claude, activate Frontend Developer mode and help me build a React component"</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Option 2: Use as Reference</h3><a id="user-content-option-2-use-as-reference" class="anchor" aria-label="Permalink: Option 2: Use as Reference" href="#option-2-use-as-reference"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Each agent file contains:</p>
<ul dir="auto">
<li>Identity &amp; personality traits</li>
<li>Core mission &amp; workflows</li>
<li>Technical deliverables with code examples</li>
<li>Success metrics &amp; communication style</li>
</ul>
<p dir="auto">Browse the agents below and copy/adapt the ones you need!</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Option 3: Use with Other Tools (Cursor, Aider, Windsurf, Gemini CLI, OpenCode)</h3><a id="user-content-option-3-use-with-other-tools-cursor-aider-windsurf-gemini-cli-opencode" class="anchor" aria-label="Permalink: Option 3: Use with Other Tools (Cursor, Aider, Windsurf, Gemini CLI, OpenCode)" href="#option-3-use-with-other-tools-cursor-aider-windsurf-gemini-cli-opencode"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Step 1 -- generate integration files for all supported tools
./scripts/convert.sh

# Step 2 -- install interactively (auto-detects what you have installed)
./scripts/install.sh

# Or target a specific tool directly
./scripts/install.sh --tool cursor
./scripts/install.sh --tool copilot
./scripts/install.sh --tool aider
./scripts/install.sh --tool windsurf"><pre><span class="pl-c"><span class="pl-c">#</span> Step 1 -- generate integration files for all supported tools</span>
./scripts/convert.sh

<span class="pl-c"><span class="pl-c">#</span> Step 2 -- install interactively (auto-detects what you have installed)</span>
./scripts/install.sh

<span class="pl-c"><span class="pl-c">#</span> Or target a specific tool directly</span>
./scripts/install.sh --tool cursor
./scripts/install.sh --tool copilot
./scripts/install.sh --tool aider
./scripts/install.sh --tool windsurf</pre></div>
<p dir="auto">See the <a href="#-multi-tool-integrations">Multi-Tool Integrations</a> section below for full details.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🎨 The Agency Roster</h2><a id="user-content--the-agency-roster" class="anchor" aria-label="Permalink: 🎨 The Agency Roster" href="#-the-agency-roster"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">💻 Engineering Division</h3><a id="user-content--engineering-division" class="anchor" aria-label="Permalink: 💻 Engineering Division" href="#-engineering-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Building the future, one commit at a time.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎨 <a href="engineering/engineering-frontend-developer.md">Frontend Developer</a></td>
<td>React/Vue/Angular, UI implementation, performance</td>
<td>Modern web apps, pixel-perfect UIs, Core Web Vitals optimization</td>
</tr>
<tr>
<td>🏗️ <a href="engineering/engineering-backend-architect.md">Backend Architect</a></td>
<td>API design, database architecture, scalability</td>
<td>Server-side systems, microservices, cloud infrastructure</td>
</tr>
<tr>
<td>📱 <a href="engineering/engineering-mobile-app-builder.md">Mobile App Builder</a></td>
<td>iOS/Android, React Native, Flutter</td>
<td>Native and cross-platform mobile applications</td>
</tr>
<tr>
<td>🤖 <a href="engineering/engineering-ai-engineer.md">AI Engineer</a></td>
<td>ML models, deployment, AI integration</td>
<td>Machine learning features, data pipelines, AI-powered apps</td>
</tr>
<tr>
<td>🚀 <a href="engineering/engineering-devops-automator.md">DevOps Automator</a></td>
<td>CI/CD, infrastructure automation, cloud ops</td>
<td>Pipeline development, deployment automation, monitoring</td>
</tr>
<tr>
<td>⚡ <a href="engineering/engineering-rapid-prototyper.md">Rapid Prototyper</a></td>
<td>Fast POC development, MVPs</td>
<td>Quick proof-of-concepts, hackathon projects, fast iteration</td>
</tr>
<tr>
<td>💎 <a href="engineering/engineering-senior-developer.md">Senior Developer</a></td>
<td>Laravel/Livewire, advanced patterns</td>
<td>Complex implementations, architecture decisions</td>
</tr>
<tr>
<td>🔒 <a href="engineering/engineering-security-engineer.md">Security Engineer</a></td>
<td>Threat modeling, secure code review, security architecture</td>
<td>Application security, vulnerability assessment, security CI/CD</td>
</tr>
<tr>
<td>⚡ <a href="engineering/engineering-autonomous-optimization-architect.md">Autonomous Optimization Architect</a></td>
<td>LLM routing, cost optimization, shadow testing</td>
<td>Autonomous systems needing intelligent API selection and cost guardrails</td>
</tr>
<tr>
<td>🔩 <a href="engineering/engineering-embedded-firmware-engineer.md">Embedded Firmware Engineer</a></td>
<td>Bare-metal, RTOS, ESP32/STM32/Nordic firmware</td>
<td>Production-grade embedded systems and IoT devices</td>
</tr>
<tr>
<td>🚨 <a href="engineering/engineering-incident-response-commander.md">Incident Response Commander</a></td>
<td>Incident management, post-mortems, on-call</td>
<td>Managing production incidents and building incident readiness</td>
</tr>
<tr>
<td>⛓️ <a href="engineering/engineering-solidity-smart-contract-engineer.md">Solidity Smart Contract Engineer</a></td>
<td>EVM contracts, gas optimization, DeFi</td>
<td>Secure, gas-optimized smart contracts and DeFi protocols</td>
</tr>
<tr>
<td>📚 <a href="engineering/engineering-technical-writer.md">Technical Writer</a></td>
<td>Developer docs, API reference, tutorials</td>
<td>Clear, accurate technical documentation</td>
</tr>
<tr>
<td>🎯 <a href="engineering/engineering-threat-detection-engineer.md">Threat Detection Engineer</a></td>
<td>SIEM rules, threat hunting, ATT&amp;CK mapping</td>
<td>Building detection layers and threat hunting</td>
</tr>
<tr>
<td>💬 <a href="engineering/engineering-wechat-mini-program-developer.md">WeChat Mini Program Developer</a></td>
<td>WeChat ecosystem, Mini Programs, payment integration</td>
<td>Building performant apps for the WeChat ecosystem</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🎨 Design Division</h3><a id="user-content--design-division" class="anchor" aria-label="Permalink: 🎨 Design Division" href="#-design-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Making it beautiful, usable, and delightful.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎯 <a href="design/design-ui-designer.md">UI Designer</a></td>
<td>Visual design, component libraries, design systems</td>
<td>Interface creation, brand consistency, component design</td>
</tr>
<tr>
<td>🔍 <a href="design/design-ux-researcher.md">UX Researcher</a></td>
<td>User testing, behavior analysis, research</td>
<td>Understanding users, usability testing, design insights</td>
</tr>
<tr>
<td>🏛️ <a href="design/design-ux-architect.md">UX Architect</a></td>
<td>Technical architecture, CSS systems, implementation</td>
<td>Developer-friendly foundations, implementation guidance</td>
</tr>
<tr>
<td>🎭 <a href="design/design-brand-guardian.md">Brand Guardian</a></td>
<td>Brand identity, consistency, positioning</td>
<td>Brand strategy, identity development, guidelines</td>
</tr>
<tr>
<td>📖 <a href="design/design-visual-storyteller.md">Visual Storyteller</a></td>
<td>Visual narratives, multimedia content</td>
<td>Compelling visual stories, brand storytelling</td>
</tr>
<tr>
<td>✨ <a href="design/design-whimsy-injector.md">Whimsy Injector</a></td>
<td>Personality, delight, playful interactions</td>
<td>Adding joy, micro-interactions, Easter eggs, brand personality</td>
</tr>
<tr>
<td>📷 <a href="design/design-image-prompt-engineer.md">Image Prompt Engineer</a></td>
<td>AI image generation prompts, photography</td>
<td>Photography prompts for Midjourney, DALL-E, Stable Diffusion</td>
</tr>
<tr>
<td>🌈 <a href="design/design-inclusive-visuals-specialist.md">Inclusive Visuals Specialist</a></td>
<td>Representation, bias mitigation, authentic imagery</td>
<td>Generating culturally accurate AI images and video</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">💰 Paid Media Division</h3><a id="user-content--paid-media-division" class="anchor" aria-label="Permalink: 💰 Paid Media Division" href="#-paid-media-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Turning ad spend into measurable business outcomes.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>💰 <a href="paid-media/paid-media-ppc-strategist.md">PPC Campaign Strategist</a></td>
<td>Google/Microsoft/Amazon Ads, account architecture, bidding</td>
<td>Account buildouts, budget allocation, scaling, performance diagnosis</td>
</tr>
<tr>
<td>🔍 <a href="paid-media/paid-media-search-query-analyst.md">Search Query Analyst</a></td>
<td>Search term analysis, negative keywords, intent mapping</td>
<td>Query audits, wasted spend elimination, keyword discovery</td>
</tr>
<tr>
<td>📋 <a href="paid-media/paid-media-auditor.md">Paid Media Auditor</a></td>
<td>200+ point account audits, competitive analysis</td>
<td>Account takeovers, quarterly reviews, competitive pitches</td>
</tr>
<tr>
<td>📡 <a href="paid-media/paid-media-tracking-specialist.md">Tracking &amp; Measurement Specialist</a></td>
<td>GTM, GA4, conversion tracking, CAPI</td>
<td>New implementations, tracking audits, platform migrations</td>
</tr>
<tr>
<td>✍️ <a href="paid-media/paid-media-creative-strategist.md">Ad Creative Strategist</a></td>
<td>RSA copy, Meta creative, Performance Max assets</td>
<td>Creative launches, testing programs, ad fatigue refreshes</td>
</tr>
<tr>
<td>📺 <a href="paid-media/paid-media-programmatic-buyer.md">Programmatic &amp; Display Buyer</a></td>
<td>GDN, DSPs, partner media, ABM display</td>
<td>Display planning, partner outreach, ABM programs</td>
</tr>
<tr>
<td>📱 <a href="paid-media/paid-media-paid-social-strategist.md">Paid Social Strategist</a></td>
<td>Meta, LinkedIn, TikTok, cross-platform social</td>
<td>Social ad programs, platform selection, audience strategy</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">💼 Sales Division</h3><a id="user-content--sales-division" class="anchor" aria-label="Permalink: 💼 Sales Division" href="#-sales-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Turning pipeline into revenue through craft, not CRM busywork.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎯 <a href="sales/sales-outbound-strategist.md">Outbound Strategist</a></td>
<td>Signal-based prospecting, multi-channel sequences, ICP targeting</td>
<td>Building pipeline through research-driven outreach, not volume</td>
</tr>
<tr>
<td>🔍 <a href="sales/sales-discovery-coach.md">Discovery Coach</a></td>
<td>SPIN, Gap Selling, Sandler — question design and call structure</td>
<td>Preparing for discovery calls, qualifying opportunities, coaching reps</td>
</tr>
<tr>
<td>♟️ <a href="sales/sales-deal-strategist.md">Deal Strategist</a></td>
<td>MEDDPICC qualification, competitive positioning, win planning</td>
<td>Scoring deals, exposing pipeline risk, building win strategies</td>
</tr>
<tr>
<td>🛠️ <a href="sales/sales-engineer.md">Sales Engineer</a></td>
<td>Technical demos, POC scoping, competitive battlecards</td>
<td>Pre-sales technical wins, demo prep, competitive positioning</td>
</tr>
<tr>
<td>🏹 <a href="sales/sales-proposal-strategist.md">Proposal Strategist</a></td>
<td>RFP response, win themes, narrative structure</td>
<td>Writing proposals that persuade, not just comply</td>
</tr>
<tr>
<td>📊 <a href="sales/sales-pipeline-analyst.md">Pipeline Analyst</a></td>
<td>Forecasting, pipeline health, deal velocity, RevOps</td>
<td>Pipeline reviews, forecast accuracy, revenue operations</td>
</tr>
<tr>
<td>🗺️ <a href="sales/sales-account-strategist.md">Account Strategist</a></td>
<td>Land-and-expand, QBRs, stakeholder mapping</td>
<td>Post-sale expansion, account planning, NRR growth</td>
</tr>
<tr>
<td>🏋️ <a href="sales/sales-coach.md">Sales Coach</a></td>
<td>Rep development, call coaching, pipeline review facilitation</td>
<td>Making every rep and every deal better through structured coaching</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">📢 Marketing Division</h3><a id="user-content--marketing-division" class="anchor" aria-label="Permalink: 📢 Marketing Division" href="#-marketing-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Growing your audience, one authentic interaction at a time.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🚀 <a href="marketing/marketing-growth-hacker.md">Growth Hacker</a></td>
<td>Rapid user acquisition, viral loops, experiments</td>
<td>Explosive growth, user acquisition, conversion optimization</td>
</tr>
<tr>
<td>📝 <a href="marketing/marketing-content-creator.md">Content Creator</a></td>
<td>Multi-platform content, editorial calendars</td>
<td>Content strategy, copywriting, brand storytelling</td>
</tr>
<tr>
<td>🐦 <a href="marketing/marketing-twitter-engager.md">Twitter Engager</a></td>
<td>Real-time engagement, thought leadership</td>
<td>Twitter strategy, LinkedIn campaigns, professional social</td>
</tr>
<tr>
<td>📱 <a href="marketing/marketing-tiktok-strategist.md">TikTok Strategist</a></td>
<td>Viral content, algorithm optimization</td>
<td>TikTok growth, viral content, Gen Z/Millennial audience</td>
</tr>
<tr>
<td>📸 <a href="marketing/marketing-instagram-curator.md">Instagram Curator</a></td>
<td>Visual storytelling, community building</td>
<td>Instagram strategy, aesthetic development, visual content</td>
</tr>
<tr>
<td>🤝 <a href="marketing/marketing-reddit-community-builder.md">Reddit Community Builder</a></td>
<td>Authentic engagement, value-driven content</td>
<td>Reddit strategy, community trust, authentic marketing</td>
</tr>
<tr>
<td>📱 <a href="marketing/marketing-app-store-optimizer.md">App Store Optimizer</a></td>
<td>ASO, conversion optimization, discoverability</td>
<td>App marketing, store optimization, app growth</td>
</tr>
<tr>
<td>🌐 <a href="marketing/marketing-social-media-strategist.md">Social Media Strategist</a></td>
<td>Cross-platform strategy, campaigns</td>
<td>Overall social strategy, multi-platform campaigns</td>
</tr>
<tr>
<td>📕 <a href="marketing/marketing-xiaohongshu-specialist.md">Xiaohongshu Specialist</a></td>
<td>Lifestyle content, trend-driven strategy</td>
<td>Xiaohongshu growth, aesthetic storytelling, Gen Z audience</td>
</tr>
<tr>
<td>💬 <a href="marketing/marketing-wechat-official-account.md">WeChat Official Account Manager</a></td>
<td>Subscriber engagement, content marketing</td>
<td>WeChat OA strategy, community building, conversion optimization</td>
</tr>
<tr>
<td>🧠 <a href="marketing/marketing-zhihu-strategist.md">Zhihu Strategist</a></td>
<td>Thought leadership, knowledge-driven engagement</td>
<td>Zhihu authority building, Q&amp;A strategy, lead generation</td>
</tr>
<tr>
<td>🇨🇳 <a href="marketing/marketing-baidu-seo-specialist.md">Baidu SEO Specialist</a></td>
<td>Baidu optimization, China SEO, ICP compliance</td>
<td>Ranking in Baidu and reaching China's search market</td>
</tr>
<tr>
<td>🎬 <a href="marketing/marketing-bilibili-content-strategist.md">Bilibili Content Strategist</a></td>
<td>B站 algorithm, danmaku culture, UP主 growth</td>
<td>Building audiences on Bilibili with community-first content</td>
</tr>
<tr>
<td>🎠 <a href="marketing/marketing-carousel-growth-engine.md">Carousel Growth Engine</a></td>
<td>TikTok/Instagram carousels, autonomous publishing</td>
<td>Generating and publishing viral carousel content</td>
</tr>
<tr>
<td>💼 <a href="marketing/marketing-linkedin-content-creator.md">LinkedIn Content Creator</a></td>
<td>Personal branding, thought leadership, professional content</td>
<td>LinkedIn growth, professional audience building, B2B content</td>
</tr>
<tr>
<td>🛒 <a href="marketing/marketing-china-ecommerce-operator.md">China E-Commerce Operator</a></td>
<td>Taobao, Tmall, Pinduoduo, live commerce</td>
<td>Running multi-platform e-commerce in China</td>
</tr>
<tr>
<td>🎥 <a href="marketing/marketing-kuaishou-strategist.md">Kuaishou Strategist</a></td>
<td>Kuaishou, 老铁 community, grassroots growth</td>
<td>Building authentic audiences in lower-tier markets</td>
</tr>
<tr>
<td>🔍 <a href="marketing/marketing-seo-specialist.md">SEO Specialist</a></td>
<td>Technical SEO, content strategy, link building</td>
<td>Driving sustainable organic search growth</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">📊 Product Division</h3><a id="user-content--product-division" class="anchor" aria-label="Permalink: 📊 Product Division" href="#-product-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Building the right thing at the right time.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎯 <a href="product/product-sprint-prioritizer.md">Sprint Prioritizer</a></td>
<td>Agile planning, feature prioritization</td>
<td>Sprint planning, resource allocation, backlog management</td>
</tr>
<tr>
<td>🔍 <a href="product/product-trend-researcher.md">Trend Researcher</a></td>
<td>Market intelligence, competitive analysis</td>
<td>Market research, opportunity assessment, trend identification</td>
</tr>
<tr>
<td>💬 <a href="product/product-feedback-synthesizer.md">Feedback Synthesizer</a></td>
<td>User feedback analysis, insights extraction</td>
<td>Feedback analysis, user insights, product priorities</td>
</tr>
<tr>
<td>🧠 <a href="product/product-behavioral-nudge-engine.md">Behavioral Nudge Engine</a></td>
<td>Behavioral psychology, nudge design, engagement</td>
<td>Maximizing user motivation through behavioral science</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🎬 Project Management Division</h3><a id="user-content--project-management-division" class="anchor" aria-label="Permalink: 🎬 Project Management Division" href="#-project-management-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Keeping the trains running on time (and under budget).</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎬 <a href="project-management/project-management-studio-producer.md">Studio Producer</a></td>
<td>High-level orchestration, portfolio management</td>
<td>Multi-project oversight, strategic alignment, resource allocation</td>
</tr>
<tr>
<td>🐑 <a href="project-management/project-management-project-shepherd.md">Project Shepherd</a></td>
<td>Cross-functional coordination, timeline management</td>
<td>End-to-end project coordination, stakeholder management</td>
</tr>
<tr>
<td>⚙️ <a href="project-management/project-management-studio-operations.md">Studio Operations</a></td>
<td>Day-to-day efficiency, process optimization</td>
<td>Operational excellence, team support, productivity</td>
</tr>
<tr>
<td>🧪 <a href="project-management/project-management-experiment-tracker.md">Experiment Tracker</a></td>
<td>A/B tests, hypothesis validation</td>
<td>Experiment management, data-driven decisions, testing</td>
</tr>
<tr>
<td>👔 <a href="project-management/project-manager-senior.md">Senior Project Manager</a></td>
<td>Realistic scoping, task conversion</td>
<td>Converting specs to tasks, scope management</td>
</tr>
<tr>
<td>📋 <a href="project-management/project-management-jira-workflow-steward.md">Jira Workflow Steward</a></td>
<td>Git workflow, branch strategy, traceability</td>
<td>Enforcing Jira-linked Git discipline and delivery</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🧪 Testing Division</h3><a id="user-content--testing-division" class="anchor" aria-label="Permalink: 🧪 Testing Division" href="#-testing-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Breaking things so users don't have to.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>📸 <a href="testing/testing-evidence-collector.md">Evidence Collector</a></td>
<td>Screenshot-based QA, visual proof</td>
<td>UI testing, visual verification, bug documentation</td>
</tr>
<tr>
<td>🔍 <a href="testing/testing-reality-checker.md">Reality Checker</a></td>
<td>Evidence-based certification, quality gates</td>
<td>Production readiness, quality approval, release certification</td>
</tr>
<tr>
<td>📊 <a href="testing/testing-test-results-analyzer.md">Test Results Analyzer</a></td>
<td>Test evaluation, metrics analysis</td>
<td>Test output analysis, quality insights, coverage reporting</td>
</tr>
<tr>
<td>⚡ <a href="testing/testing-performance-benchmarker.md">Performance Benchmarker</a></td>
<td>Performance testing, optimization</td>
<td>Speed testing, load testing, performance tuning</td>
</tr>
<tr>
<td>🔌 <a href="testing/testing-api-tester.md">API Tester</a></td>
<td>API validation, integration testing</td>
<td>API testing, endpoint verification, integration QA</td>
</tr>
<tr>
<td>🛠️ <a href="testing/testing-tool-evaluator.md">Tool Evaluator</a></td>
<td>Technology assessment, tool selection</td>
<td>Evaluating tools, software recommendations, tech decisions</td>
</tr>
<tr>
<td>🔄 <a href="testing/testing-workflow-optimizer.md">Workflow Optimizer</a></td>
<td>Process analysis, workflow improvement</td>
<td>Process optimization, efficiency gains, automation opportunities</td>
</tr>
<tr>
<td>♿ <a href="testing/testing-accessibility-auditor.md">Accessibility Auditor</a></td>
<td>WCAG auditing, assistive technology testing</td>
<td>Accessibility compliance, screen reader testing, inclusive design verification</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🛟 Support Division</h3><a id="user-content--support-division" class="anchor" aria-label="Permalink: 🛟 Support Division" href="#-support-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The backbone of the operation.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>💬 <a href="support/support-support-responder.md">Support Responder</a></td>
<td>Customer service, issue resolution</td>
<td>Customer support, user experience, support operations</td>
</tr>
<tr>
<td>📊 <a href="support/support-analytics-reporter.md">Analytics Reporter</a></td>
<td>Data analysis, dashboards, insights</td>
<td>Business intelligence, KPI tracking, data visualization</td>
</tr>
<tr>
<td>💰 <a href="support/support-finance-tracker.md">Finance Tracker</a></td>
<td>Financial planning, budget management</td>
<td>Financial analysis, cash flow, business performance</td>
</tr>
<tr>
<td>🏗️ <a href="support/support-infrastructure-maintainer.md">Infrastructure Maintainer</a></td>
<td>System reliability, performance optimization</td>
<td>Infrastructure management, system operations, monitoring</td>
</tr>
<tr>
<td>⚖️ <a href="support/support-legal-compliance-checker.md">Legal Compliance Checker</a></td>
<td>Compliance, regulations, legal review</td>
<td>Legal compliance, regulatory requirements, risk management</td>
</tr>
<tr>
<td>📑 <a href="support/support-executive-summary-generator.md">Executive Summary Generator</a></td>
<td>C-suite communication, strategic summaries</td>
<td>Executive reporting, strategic communication, decision support</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🥽 Spatial Computing Division</h3><a id="user-content--spatial-computing-division" class="anchor" aria-label="Permalink: 🥽 Spatial Computing Division" href="#-spatial-computing-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Building the immersive future.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🏗️ <a href="spatial-computing/xr-interface-architect.md">XR Interface Architect</a></td>
<td>Spatial interaction design, immersive UX</td>
<td>AR/VR/XR interface design, spatial computing UX</td>
</tr>
<tr>
<td>💻 <a href="spatial-computing/macos-spatial-metal-engineer.md">macOS Spatial/Metal Engineer</a></td>
<td>Swift, Metal, high-performance 3D</td>
<td>macOS spatial computing, Vision Pro native apps</td>
</tr>
<tr>
<td>🌐 <a href="spatial-computing/xr-immersive-developer.md">XR Immersive Developer</a></td>
<td>WebXR, browser-based AR/VR</td>
<td>Browser-based immersive experiences, WebXR apps</td>
</tr>
<tr>
<td>🎮 <a href="spatial-computing/xr-cockpit-interaction-specialist.md">XR Cockpit Interaction Specialist</a></td>
<td>Cockpit-based controls, immersive systems</td>
<td>Cockpit control systems, immersive control interfaces</td>
</tr>
<tr>
<td>🍎 <a href="spatial-computing/visionos-spatial-engineer.md">visionOS Spatial Engineer</a></td>
<td>Apple Vision Pro development</td>
<td>Vision Pro apps, spatial computing experiences</td>
</tr>
<tr>
<td>🔌 <a href="spatial-computing/terminal-integration-specialist.md">Terminal Integration Specialist</a></td>
<td>Terminal integration, command-line tools</td>
<td>CLI tools, terminal workflows, developer tools</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🎯 Specialized Division</h3><a id="user-content--specialized-division" class="anchor" aria-label="Permalink: 🎯 Specialized Division" href="#-specialized-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The unique specialists who don't fit in a box.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎭 <a href="specialized/agents-orchestrator.md">Agents Orchestrator</a></td>
<td>Multi-agent coordination, workflow management</td>
<td>Complex projects requiring multiple agent coordination</td>
</tr>
<tr>
<td>🔍 <a href="specialized/lsp-index-engineer.md">LSP/Index Engineer</a></td>
<td>Language Server Protocol, code intelligence</td>
<td>Code intelligence systems, LSP implementation, semantic indexing</td>
</tr>
<tr>
<td>📥 <a href="specialized/sales-data-extraction-agent.md">Sales Data Extraction Agent</a></td>
<td>Excel monitoring, sales metric extraction</td>
<td>Sales data ingestion, MTD/YTD/Year End metrics</td>
</tr>
<tr>
<td>📈 <a href="specialized/data-consolidation-agent.md">Data Consolidation Agent</a></td>
<td>Sales data aggregation, dashboard reports</td>
<td>Territory summaries, rep performance, pipeline snapshots</td>
</tr>
<tr>
<td>📬 <a href="specialized/report-distribution-agent.md">Report Distribution Agent</a></td>
<td>Automated report delivery</td>
<td>Territory-based report distribution, scheduled sends</td>
</tr>
<tr>
<td>🔐 <a href="specialized/agentic-identity-trust.md">Agentic Identity &amp; Trust Architect</a></td>
<td>Agent identity, authentication, trust verification</td>
<td>Multi-agent identity systems, agent authorization, audit trails</td>
</tr>
<tr>
<td>🔗 <a href="specialized/identity-graph-operator.md">Identity Graph Operator</a></td>
<td>Shared identity resolution for multi-agent systems</td>
<td>Entity deduplication, merge proposals, cross-agent identity consistency</td>
</tr>
<tr>
<td>💸 <a href="specialized/accounts-payable-agent.md">Accounts Payable Agent</a></td>
<td>Payment processing, vendor management, audit</td>
<td>Autonomous payment execution across crypto, fiat, stablecoins</td>
</tr>
<tr>
<td>🛡️ <a href="specialized/blockchain-security-auditor.md">Blockchain Security Auditor</a></td>
<td>Smart contract audits, exploit analysis</td>
<td>Finding vulnerabilities in contracts before deployment</td>
</tr>
<tr>
<td>📋 <a href="specialized/compliance-auditor.md">Compliance Auditor</a></td>
<td>SOC 2, ISO 27001, HIPAA, PCI-DSS</td>
<td>Guiding organizations through compliance certification</td>
</tr>
<tr>
<td>🌍 <a href="specialized/specialized-cultural-intelligence-strategist.md">Cultural Intelligence Strategist</a></td>
<td>Global UX, representation, cultural exclusion</td>
<td>Ensuring software resonates across cultures</td>
</tr>
<tr>
<td>🗣️ <a href="specialized/specialized-developer-advocate.md">Developer Advocate</a></td>
<td>Community building, DX, developer content</td>
<td>Bridging product and developer community</td>
</tr>
<tr>
<td>🔬 <a href="specialized/specialized-model-qa.md">Model QA Specialist</a></td>
<td>ML audits, feature analysis, interpretability</td>
<td>End-to-end QA for machine learning models</td>
</tr>
<tr>
<td>🗃️ <a href="specialized/zk-steward.md">ZK Steward</a></td>
<td>Knowledge management, Zettelkasten, notes</td>
<td>Building connected, validated knowledge bases</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🎮 Game Development Division</h3><a id="user-content--game-development-division" class="anchor" aria-label="Permalink: 🎮 Game Development Division" href="#-game-development-division"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Building worlds, systems, and experiences across every major engine.</p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Cross-Engine Agents (Engine-Agnostic)</h4><a id="user-content-cross-engine-agents-engine-agnostic" class="anchor" aria-label="Permalink: Cross-Engine Agents (Engine-Agnostic)" href="#cross-engine-agents-engine-agnostic"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🎯 <a href="game-development/game-designer.md">Game Designer</a></td>
<td>Systems design, GDD authorship, economy balancing, gameplay loops</td>
<td>Designing game mechanics, progression systems, writing design documents</td>
</tr>
<tr>
<td>🗺️ <a href="game-development/level-designer.md">Level Designer</a></td>
<td>Layout theory, pacing, encounter design, environmental storytelling</td>
<td>Building levels, designing encounter flow, spatial narrative</td>
</tr>
<tr>
<td>🎨 <a href="game-development/technical-artist.md">Technical Artist</a></td>
<td>Shaders, VFX, LOD pipeline, art-to-engine optimization</td>
<td>Bridging art and engineering, shader authoring, performance-safe asset pipelines</td>
</tr>
<tr>
<td>🔊 <a href="game-development/game-audio-engineer.md">Game Audio Engineer</a></td>
<td>FMOD/Wwise, adaptive music, spatial audio, audio budgets</td>
<td>Interactive audio systems, dynamic music, audio performance</td>
</tr>
<tr>
<td>📖 <a href="game-development/narrative-designer.md">Narrative Designer</a></td>
<td>Story systems, branching dialogue, lore architecture</td>
<td>Writing branching narratives, implementing dialogue systems, world lore</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Unity</h4><a id="user-content-unity" class="anchor" aria-label="Permalink: Unity" href="#unity"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>🏗️ <a href="game-development/unity/unity-architect.md">Unity Architect</a></td>
<td>ScriptableObjects, data-driven modularity, DOTS/ECS</td>
<td>Large-scale Unity projects, data-driven system design, ECS performance work</td>
</tr>
<tr>
<td>✨ <a href="game-development/unity/unity-shader-graph-artist.md">Unity Shader Graph Artist</a></td>
<td>Shader Graph, HLSL, URP/HDRP, Renderer Features</td>
<td>Custom Unity materials, VFX shaders, post-processing passes</td>
</tr>
<tr>
<td>🌐 <a href="game-development/unity/unity-multiplayer-engineer.md">Unity Multiplayer Engineer</a></td>
<td>Netcode for GameObjects, Unity Relay/Lobby, server authority, prediction</td>
<td>Online Unity games, client prediction, Unity Gaming Services integration</td>
</tr>
<tr>
<td>🛠️ <a href="game-development/unity/unity-editor-tool-developer.md">Unity Editor Tool Developer</a></td>
<td>EditorWindows, AssetPostprocessors, PropertyDrawers, build validation</td>
<td>Custom Unity Editor tooling, pipeline automation, content validation</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Unreal Engine</h4><a id="user-content-unreal-engine" class="anchor" aria-label="Permalink: Unreal Engine" href="#unreal-engine"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>⚙️ <a href="game-development/unreal-engine/unreal-systems-engineer.md">Unreal Systems Engineer</a></td>
<td>C++/Blueprint hybrid, GAS, Nanite constraints, memory management</td>
<td>Complex Unreal gameplay systems, Gameplay Ability System, engine-level C++</td>
</tr>
<tr>
<td>🎨 <a href="game-development/unreal-engine/unreal-technical-artist.md">Unreal Technical Artist</a></td>
<td>Material Editor, Niagara, PCG, Substrate</td>
<td>Unreal materials, Niagara VFX, procedural content generation</td>
</tr>
<tr>
<td>🌐 <a href="game-development/unreal-engine/unreal-multiplayer-architect.md">Unreal Multiplayer Architect</a></td>
<td>Actor replication, GameMode/GameState hierarchy, dedicated server</td>
<td>Unreal online games, replication graphs, server authoritative Unreal</td>
</tr>
<tr>
<td>🗺️ <a href="game-development/unreal-engine/unreal-world-builder.md">Unreal World Builder</a></td>
<td>World Partition, Landscape, HLOD, LWC</td>
<td>Large open-world Unreal levels, streaming systems, terrain at scale</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Godot</h4><a id="user-content-godot" class="anchor" aria-label="Permalink: Godot" href="#godot"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>📜 <a href="game-development/godot/godot-gameplay-scripter.md">Godot Gameplay Scripter</a></td>
<td>GDScript 2.0, signals, composition, static typing</td>
<td>Godot gameplay systems, scene composition, performance-conscious GDScript</td>
</tr>
<tr>
<td>🌐 <a href="game-development/godot/godot-multiplayer-engineer.md">Godot Multiplayer Engineer</a></td>
<td>MultiplayerAPI, ENet/WebRTC, RPCs, authority model</td>
<td>Online Godot games, scene replication, server-authoritative Godot</td>
</tr>
<tr>
<td>✨ <a href="game-development/godot/godot-shader-developer.md">Godot Shader Developer</a></td>
<td>Godot shading language, VisualShader, RenderingDevice</td>
<td>Custom Godot materials, 2D/3D effects, post-processing, compute shaders</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Roblox Studio</h4><a id="user-content-roblox-studio" class="anchor" aria-label="Permalink: Roblox Studio" href="#roblox-studio"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Agent</th>
<th>Specialty</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td>⚙️ <a href="game-development/roblox-studio/roblox-systems-scripter.md">Roblox Systems Scripter</a></td>
<td>Luau, RemoteEvents/Functions, DataStore, server-authoritative module architecture</td>
<td>Building secure Roblox game systems, client-server communication, data persistence</td>
</tr>
<tr>
<td>🎯 <a href="game-development/roblox-studio/roblox-experience-designer.md">Roblox Experience Designer</a></td>
<td>Engagement loops, monetization, D1/D7 retention, onboarding flow</td>
<td>Designing Roblox game loops, Game Passes, daily rewards, player retention</td>
</tr>
<tr>
<td>👗 <a href="game-development/roblox-studio/roblox-avatar-creator.md">Roblox Avatar Creator</a></td>
<td>UGC pipeline, accessory rigging, Creator Marketplace submission</td>
<td>Roblox UGC items, HumanoidDescription customization, in-experience avatar shops</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🎯 Real-World Use Cases</h2><a id="user-content--real-world-use-cases" class="anchor" aria-label="Permalink: 🎯 Real-World Use Cases" href="#-real-world-use-cases"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Scenario 1: Building a Startup MVP</h3><a id="user-content-scenario-1-building-a-startup-mvp" class="anchor" aria-label="Permalink: Scenario 1: Building a Startup MVP" href="#scenario-1-building-a-startup-mvp"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Your Team</strong>:</p>
<ol dir="auto">
<li>🎨 <strong>Frontend Developer</strong> - Build the React app</li>
<li>🏗️ <strong>Backend Architect</strong> - Design the API and database</li>
<li>🚀 <strong>Growth Hacker</strong> - Plan user acquisition</li>
<li>⚡ <strong>Rapid Prototyper</strong> - Fast iteration cycles</li>
<li>🔍 <strong>Reality Checker</strong> - Ensure quality before launch</li>
</ol>
<p dir="auto"><strong>Result</strong>: Ship faster with specialized expertise at every stage.</p>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Scenario 2: Marketing Campaign Launch</h3><a id="user-content-scenario-2-marketing-campaign-launch" class="anchor" aria-label="Permalink: Scenario 2: Marketing Campaign Launch" href="#scenario-2-marketing-campaign-launch"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Your Team</strong>:</p>
<ol dir="auto">
<li>📝 <strong>Content Creator</strong> - Develop campaign content</li>
<li>🐦 <strong>Twitter Engager</strong> - Twitter strategy and execution</li>
<li>📸 <strong>Instagram Curator</strong> - Visual content and stories</li>
<li>🤝 <strong>Reddit Community Builder</strong> - Authentic community engagement</li>
<li>📊 <strong>Analytics Reporter</strong> - Track and optimize performance</li>
</ol>
<p dir="auto"><strong>Result</strong>: Multi-channel coordinated campaign with platform-specific expertise.</p>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Scenario 3: Enterprise Feature Development</h3><a id="user-content-scenario-3-enterprise-feature-development" class="anchor" aria-label="Permalink: Scenario 3: Enterprise Feature Development" href="#scenario-3-enterprise-feature-development"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Your Team</strong>:</p>
<ol dir="auto">
<li>👔 <strong>Senior Project Manager</strong> - Scope and task planning</li>
<li>💎 <strong>Senior Developer</strong> - Complex implementation</li>
<li>🎨 <strong>UI Designer</strong> - Design system and components</li>
<li>🧪 <strong>Experiment Tracker</strong> - A/B test planning</li>
<li>📸 <strong>Evidence Collector</strong> - Quality verification</li>
<li>🔍 <strong>Reality Checker</strong> - Production readiness</li>
</ol>
<p dir="auto"><strong>Result</strong>: Enterprise-grade delivery with quality gates and documentation.</p>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Scenario 5: Paid Media Account Takeover</h3><a id="user-content-scenario-5-paid-media-account-takeover" class="anchor" aria-label="Permalink: Scenario 5: Paid Media Account Takeover" href="#scenario-5-paid-media-account-takeover"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Your Team</strong>:</p>
<ol dir="auto">
<li>📋 <strong>Paid Media Auditor</strong> - Comprehensive account assessment</li>
<li>📡 <strong>Tracking &amp; Measurement Specialist</strong> - Verify conversion tracking accuracy</li>
<li>💰 <strong>PPC Campaign Strategist</strong> - Redesign account architecture</li>
<li>🔍 <strong>Search Query Analyst</strong> - Clean up wasted spend from search terms</li>
<li>✍️ <strong>Ad Creative Strategist</strong> - Refresh all ad copy and extensions</li>
<li>📊 <strong>Analytics Reporter</strong> (Support Division) - Build reporting dashboards</li>
</ol>
<p dir="auto"><strong>Result</strong>: Systematic account takeover with tracking verified, waste eliminated, structure optimized, and creative refreshed — all within the first 30 days.</p>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Scenario 4: Full Agency Product Discovery</h3><a id="user-content-scenario-4-full-agency-product-discovery" class="anchor" aria-label="Permalink: Scenario 4: Full Agency Product Discovery" href="#scenario-4-full-agency-product-discovery"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Your Team</strong>: All 8 divisions working in parallel on a single mission.</p>
<p dir="auto">See the <strong><a href="examples/nexus-spatial-discovery.md">Nexus Spatial Discovery Exercise</a></strong> -- a complete example where 8 agents (Product Trend Researcher, Backend Architect, Brand Guardian, Growth Hacker, Support Responder, UX Researcher, Project Shepherd, and XR Interface Architect) were deployed simultaneously to evaluate a software opportunity and produce a unified product plan covering market validation, technical architecture, brand strategy, go-to-market, support systems, UX research, project execution, and spatial UI design.</p>
<p dir="auto"><strong>Result</strong>: Comprehensive, cross-functional product blueprint produced in a single session. <a href="examples/">More examples</a>.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🤝 Contributing</h2><a id="user-content--contributing" class="anchor" aria-label="Permalink: 🤝 Contributing" href="#-contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">We welcome contributions! Here's how you can help:</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Add a New Agent</h3><a id="user-content-add-a-new-agent" class="anchor" aria-label="Permalink: Add a New Agent" href="#add-a-new-agent"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>Fork the repository</li>
<li>Create a new agent file in the appropriate category</li>
<li>Follow the agent template structure:
<ul dir="auto">
<li>Frontmatter with name, description, color</li>
<li>Identity &amp; Memory section</li>
<li>Core Mission</li>
<li>Critical Rules (domain-specific)</li>
<li>Technical Deliverables with examples</li>
<li>Workflow Process</li>
<li>Success Metrics</li>
</ul>
</li>
<li>Submit a PR with your agent</li>
</ol>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Improve Existing Agents</h3><a id="user-content-improve-existing-agents" class="anchor" aria-label="Permalink: Improve Existing Agents" href="#improve-existing-agents"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Add real-world examples</li>
<li>Enhance code samples</li>
<li>Update success metrics</li>
<li>Improve workflows</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Share Your Success Stories</h3><a id="user-content-share-your-success-stories" class="anchor" aria-label="Permalink: Share Your Success Stories" href="#share-your-success-stories"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Have you used these agents successfully? Share your story in the <a href="https://github.com/msitarzewski/agency-agents/discussions">Discussions</a>!</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📖 Agent Design Philosophy</h2><a id="user-content--agent-design-philosophy" class="anchor" aria-label="Permalink: 📖 Agent Design Philosophy" href="#-agent-design-philosophy"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Each agent is designed with:</p>
<ol dir="auto">
<li><strong>🎭 Strong Personality</strong>: Not generic templates - real character and voice</li>
<li><strong>📋 Clear Deliverables</strong>: Concrete outputs, not vague guidance</li>
<li><strong>✅ Success Metrics</strong>: Measurable outcomes and quality standards</li>
<li><strong>🔄 Proven Workflows</strong>: Step-by-step processes that work</li>
<li><strong>💡 Learning Memory</strong>: Pattern recognition and continuous improvement</li>
</ol>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🎁 What Makes This Special?</h2><a id="user-content--what-makes-this-special" class="anchor" aria-label="Permalink: 🎁 What Makes This Special?" href="#-what-makes-this-special"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Unlike Generic AI Prompts:</h3><a id="user-content-unlike-generic-ai-prompts" class="anchor" aria-label="Permalink: Unlike Generic AI Prompts:" href="#unlike-generic-ai-prompts"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>❌ Generic "Act as a developer" prompts</li>
<li>✅ Deep specialization with personality and process</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Unlike Prompt Libraries:</h3><a id="user-content-unlike-prompt-libraries" class="anchor" aria-label="Permalink: Unlike Prompt Libraries:" href="#unlike-prompt-libraries"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>❌ One-off prompt collections</li>
<li>✅ Comprehensive agent systems with workflows and deliverables</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Unlike AI Tools:</h3><a id="user-content-unlike-ai-tools" class="anchor" aria-label="Permalink: Unlike AI Tools:" href="#unlike-ai-tools"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>❌ Black box tools you can't customize</li>
<li>✅ Transparent, forkable, adaptable agent personalities</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🎨 Agent Personality Highlights</h2><a id="user-content--agent-personality-highlights" class="anchor" aria-label="Permalink: 🎨 Agent Personality Highlights" href="#-agent-personality-highlights"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<blockquote>
<p dir="auto">"I don't just test your code - I default to finding 3-5 issues and require visual proof for everything."</p>
<p dir="auto">-- <strong>Evidence Collector</strong> (Testing Division)</p>
</blockquote>
<blockquote>
<p dir="auto">"You're not marketing on Reddit - you're becoming a valued community member who happens to represent a brand."</p>
<p dir="auto">-- <strong>Reddit Community Builder</strong> (Marketing Division)</p>
</blockquote>
<blockquote>
<p dir="auto">"Every playful element must serve a functional or emotional purpose. Design delight that enhances rather than distracts."</p>
<p dir="auto">-- <strong>Whimsy Injector</strong> (Design Division)</p>
</blockquote>
<blockquote>
<p dir="auto">"Let me add a celebration animation that reduces task completion anxiety by 40%"</p>
<p dir="auto">-- <strong>Whimsy Injector</strong> (during a UX review)</p>
</blockquote>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📊 Stats</h2><a id="user-content--stats" class="anchor" aria-label="Permalink: 📊 Stats" href="#-stats"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>🎭 <strong>120 Specialized Agents</strong> across 12 divisions</li>
<li>📝 <strong>10,000+ lines</strong> of personality, process, and code examples</li>
<li>⏱️ <strong>Months of iteration</strong> from real-world usage</li>
<li>🌟 <strong>Battle-tested</strong> in production environments</li>
<li>💬 <strong>50+ requests</strong> in first 12 hours on Reddit</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🔌 Multi-Tool Integrations</h2><a id="user-content--multi-tool-integrations" class="anchor" aria-label="Permalink: 🔌 Multi-Tool Integrations" href="#-multi-tool-integrations"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The Agency works natively with Claude Code, and ships conversion + install scripts so you can use the same agents across every major agentic coding tool.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Supported Tools</h3><a id="user-content-supported-tools" class="anchor" aria-label="Permalink: Supported Tools" href="#supported-tools"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong><a href="https://claude.ai/code" rel="nofollow">Claude Code</a></strong> — native <code>.md</code> agents, no conversion needed → <code>~/.claude/agents/</code></li>
<li><strong><a href="https://github.com/copilot">GitHub Copilot</a></strong> — native <code>.md</code> agents, no conversion needed → <code>~/.github/agents/</code></li>
<li><strong><a href="https://github.com/google-gemini/antigravity">Antigravity</a></strong> — <code>SKILL.md</code> per agent → <code>~/.gemini/antigravity/skills/</code></li>
<li><strong><a href="https://github.com/google-gemini/gemini-cli">Gemini CLI</a></strong> — extension + <code>SKILL.md</code> files → <code>~/.gemini/extensions/agency-agents/</code></li>
<li><strong><a href="https://opencode.ai" rel="nofollow">OpenCode</a></strong> — <code>.md</code> agent files → <code>.opencode/agents/</code></li>
<li><strong><a href="https://cursor.sh" rel="nofollow">Cursor</a></strong> — <code>.mdc</code> rule files → <code>.cursor/rules/</code></li>
<li><strong><a href="https://aider.chat" rel="nofollow">Aider</a></strong> — single <code>CONVENTIONS.md</code> → <code>./CONVENTIONS.md</code></li>
<li><strong><a href="https://codeium.com/windsurf" rel="nofollow">Windsurf</a></strong> — single <code>.windsurfrules</code> → <code>./.windsurfrules</code></li>
<li><strong><a href="https://github.com/openclaw/openclaw">OpenClaw</a></strong> — <code>SOUL.md</code> + <code>AGENTS.md</code> + <code>IDENTITY.md</code> per agent</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">⚡ Quick Install</h3><a id="user-content--quick-install" class="anchor" aria-label="Permalink: ⚡ Quick Install" href="#-quick-install"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Step 1 -- Generate integration files:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/convert.sh"><pre>./scripts/convert.sh</pre></div>
<p dir="auto"><strong>Step 2 -- Install (interactive, auto-detects your tools):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh"><pre>./scripts/install.sh</pre></div>
<p dir="auto">The installer scans your system for installed tools, shows a checkbox UI, and lets you pick exactly what to install:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  +------------------------------------------------+
  |   The Agency -- Tool Installer                 |
  +------------------------------------------------+

  System scan: [*] = detected on this machine

  [x]  1)  [*]  Claude Code     (claude.ai/code)
  [x]  2)  [*]  Copilot         (~/.github/agents)
  [x]  3)  [*]  Antigravity     (~/.gemini/antigravity)
  [ ]  4)  [ ]  Gemini CLI      (gemini extension)
  [ ]  5)  [ ]  OpenCode        (opencode.ai)
  [ ]  6)  [ ]  OpenClaw        (~/.openclaw)
  [x]  7)  [*]  Cursor          (.cursor/rules)
  [ ]  8)  [ ]  Aider           (CONVENTIONS.md)
  [ ]  9)  [ ]  Windsurf        (.windsurfrules)

  [1-9] toggle   [a] all   [n] none   [d] detected
  [Enter] install   [q] quit"><pre class="notranslate"><code>  +------------------------------------------------+
  |   The Agency -- Tool Installer                 |
  +------------------------------------------------+

  System scan: [*] = detected on this machine

  [x]  1)  [*]  Claude Code     (claude.ai/code)
  [x]  2)  [*]  Copilot         (~/.github/agents)
  [x]  3)  [*]  Antigravity     (~/.gemini/antigravity)
  [ ]  4)  [ ]  Gemini CLI      (gemini extension)
  [ ]  5)  [ ]  OpenCode        (opencode.ai)
  [ ]  6)  [ ]  OpenClaw        (~/.openclaw)
  [x]  7)  [*]  Cursor          (.cursor/rules)
  [ ]  8)  [ ]  Aider           (CONVENTIONS.md)
  [ ]  9)  [ ]  Windsurf        (.windsurfrules)

  [1-9] toggle   [a] all   [n] none   [d] detected
  [Enter] install   [q] quit
</code></pre></div>
<p dir="auto"><strong>Or install a specific tool directly:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --tool cursor
./scripts/install.sh --tool opencode
./scripts/install.sh --tool openclaw
./scripts/install.sh --tool antigravity"><pre>./scripts/install.sh --tool cursor
./scripts/install.sh --tool opencode
./scripts/install.sh --tool openclaw
./scripts/install.sh --tool antigravity</pre></div>
<p dir="auto"><strong>Non-interactive (CI/scripts):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --no-interactive --tool all"><pre>./scripts/install.sh --no-interactive --tool all</pre></div>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Tool-Specific Instructions</h3><a id="user-content-tool-specific-instructions" class="anchor" aria-label="Permalink: Tool-Specific Instructions" href="#tool-specific-instructions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Claude Code</strong></summary>
<p dir="auto">Agents are copied directly from the repo into <code>~/.claude/agents/</code> -- no conversion needed.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --tool claude-code"><pre>./scripts/install.sh --tool claude-code</pre></div>
<p dir="auto">Then activate in Claude Code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Use the Frontend Developer agent to review this component."><pre class="notranslate"><code>Use the Frontend Developer agent to review this component.
</code></pre></div>
<p dir="auto">See <a href="integrations/claude-code/README.md">integrations/claude-code/README.md</a> for details.</p>
</details>
<details>
<summary><strong>GitHub Copilot</strong></summary>
<p dir="auto">Agents are copied directly from the repo into <code>~/.github/agents/</code> -- no conversion needed.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --tool copilot"><pre>./scripts/install.sh --tool copilot</pre></div>
<p dir="auto">Then activate in GitHub Copilot:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Use the Frontend Developer agent to review this component."><pre class="notranslate"><code>Use the Frontend Developer agent to review this component.
</code></pre></div>
<p dir="auto">See <a href="integrations/github-copilot/README.md">integrations/github-copilot/README.md</a> for details.</p>
</details>
<details>
<summary><strong>Antigravity (Gemini)</strong></summary>
<p dir="auto">Each agent becomes a skill in <code>~/.gemini/antigravity/skills/agency-&lt;slug&gt;/</code>.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --tool antigravity"><pre>./scripts/install.sh --tool antigravity</pre></div>
<p dir="auto">Activate in Gemini with Antigravity:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@agency-frontend-developer review this React component"><pre class="notranslate"><code>@agency-frontend-developer review this React component
</code></pre></div>
<p dir="auto">See <a href="integrations/antigravity/README.md">integrations/antigravity/README.md</a> for details.</p>
</details>
<details>
<summary><strong>Gemini CLI</strong></summary>
<p dir="auto">Installs as a Gemini CLI extension with one skill per agent plus a manifest.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --tool gemini-cli"><pre>./scripts/install.sh --tool gemini-cli</pre></div>
<p dir="auto">See <a href="integrations/gemini-cli/README.md">integrations/gemini-cli/README.md</a> for details.</p>
</details>
<details>
<summary><strong>OpenCode</strong></summary>
<p dir="auto">Agents are placed in <code>.opencode/agents/</code> in your project root (project-scoped).</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd /your/project
/path/to/agency-agents/scripts/install.sh --tool opencode"><pre><span class="pl-c1">cd</span> /your/project
/path/to/agency-agents/scripts/install.sh --tool opencode</pre></div>
<p dir="auto">Or install globally:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="mkdir -p ~/.config/opencode/agents
cp integrations/opencode/agents/*.md ~/.config/opencode/agents/"><pre>mkdir -p <span class="pl-k">~</span>/.config/opencode/agents
cp integrations/opencode/agents/<span class="pl-k">*</span>.md <span class="pl-k">~</span>/.config/opencode/agents/</pre></div>
<p dir="auto">Activate in OpenCode:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@backend-architect design this API."><pre class="notranslate"><code>@backend-architect design this API.
</code></pre></div>
<p dir="auto">See <a href="integrations/opencode/README.md">integrations/opencode/README.md</a> for details.</p>
</details>
<details>
<summary><strong>Cursor</strong></summary>
<p dir="auto">Each agent becomes a <code>.mdc</code> rule file in <code>.cursor/rules/</code> of your project.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd /your/project
/path/to/agency-agents/scripts/install.sh --tool cursor"><pre><span class="pl-c1">cd</span> /your/project
/path/to/agency-agents/scripts/install.sh --tool cursor</pre></div>
<p dir="auto">Rules are auto-applied when Cursor detects them in the project. Reference them explicitly:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Use the @security-engineer rules to review this code."><pre class="notranslate"><code>Use the @security-engineer rules to review this code.
</code></pre></div>
<p dir="auto">See <a href="integrations/cursor/README.md">integrations/cursor/README.md</a> for details.</p>
</details>
<details>
<summary><strong>Aider</strong></summary>
<p dir="auto">All agents are compiled into a single <code>CONVENTIONS.md</code> file that Aider reads automatically.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd /your/project
/path/to/agency-agents/scripts/install.sh --tool aider"><pre><span class="pl-c1">cd</span> /your/project
/path/to/agency-agents/scripts/install.sh --tool aider</pre></div>
<p dir="auto">Then reference agents in your Aider session:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Use the Frontend Developer agent to refactor this component."><pre class="notranslate"><code>Use the Frontend Developer agent to refactor this component.
</code></pre></div>
<p dir="auto">See <a href="integrations/aider/README.md">integrations/aider/README.md</a> for details.</p>
</details>
<details>
<summary><strong>Windsurf</strong></summary>
<p dir="auto">All agents are compiled into <code>.windsurfrules</code> in your project root.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd /your/project
/path/to/agency-agents/scripts/install.sh --tool windsurf"><pre><span class="pl-c1">cd</span> /your/project
/path/to/agency-agents/scripts/install.sh --tool windsurf</pre></div>
<p dir="auto">Reference agents in Windsurf's Cascade:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Use the Reality Checker agent to verify this is production ready."><pre class="notranslate"><code>Use the Reality Checker agent to verify this is production ready.
</code></pre></div>
<p dir="auto">See <a href="integrations/windsurf/README.md">integrations/windsurf/README.md</a> for details.</p>
</details>
<details>
<summary><strong>OpenClaw</strong></summary>
<p dir="auto">Each agent becomes a workspace with <code>SOUL.md</code>, <code>AGENTS.md</code>, and <code>IDENTITY.md</code> in <code>~/.openclaw/agency-agents/</code>.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/install.sh --tool openclaw"><pre>./scripts/install.sh --tool openclaw</pre></div>
<p dir="auto">Agents are registered and available by <code>agentId</code> in OpenClaw sessions.</p>
<p dir="auto">See <a href="integrations/openclaw/README.md">integrations/openclaw/README.md</a> for details.</p>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Regenerating After Changes</h3><a id="user-content-regenerating-after-changes" class="anchor" aria-label="Permalink: Regenerating After Changes" href="#regenerating-after-changes"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When you add new agents or edit existing ones, regenerate all integration files:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./scripts/convert.sh        # regenerate all
./scripts/convert.sh --tool cursor   # regenerate just one tool"><pre>./scripts/convert.sh        <span class="pl-c"><span class="pl-c">#</span> regenerate all</span>
./scripts/convert.sh --tool cursor   <span class="pl-c"><span class="pl-c">#</span> regenerate just one tool</span></pre></div>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🗺️ Roadmap</h2><a id="user-content-️-roadmap" class="anchor" aria-label="Permalink: 🗺️ Roadmap" href="#️-roadmap"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Incomplete task"> Interactive agent selector web tool</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Completed task" checked=""> Multi-agent workflow examples -- see <a href="examples/">examples/</a></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Completed task" checked=""> Multi-tool integration scripts (Claude Code, GitHub Copilot, Antigravity, Gemini CLI, OpenCode, OpenClaw, Cursor, Aider, Windsurf)</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Incomplete task"> Video tutorials on agent design</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Incomplete task"> Community agent marketplace</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Incomplete task"> Agent "personality quiz" for project matching</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" aria-label="Incomplete task"> "Agent of the Week" showcase series</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🌐 Community Translations &amp; Localizations</h2><a id="user-content--community-translations--localizations" class="anchor" aria-label="Permalink: 🌐 Community Translations &amp; Localizations" href="#-community-translations--localizations"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Community-maintained translations and regional adaptations. These are independently maintained -- see each repo for coverage and version compatibility.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Language</th>
<th>Maintainer</th>
<th>Link</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>🇨🇳 简体中文 (zh-CN)</td>
<td><a href="https://github.com/jnMetaCode">@jnMetaCode</a></td>
<td><a href="https://github.com/jnMetaCode/agency-agents-zh">agency-agents-zh</a></td>
<td>100 translated agents + 9 China-market originals</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">Want to add a translation? Open an issue and we'll link it here.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🔗 Related Resources</h2><a id="user-content--related-resources" class="anchor" aria-label="Permalink: 🔗 Related Resources" href="#-related-resources"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="https://github.com/mergisi/awesome-openclaw-agents">awesome-openclaw-agents</a> — Community-maintained OpenClaw agent collection (derived from this repo)</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📜 License</h2><a id="user-content--license" class="anchor" aria-label="Permalink: 📜 License" href="#-license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT License - Use freely, commercially or personally. Attribution appreciated but not required.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🙏 Acknowledgments</h2><a id="user-content--acknowledgments" class="anchor" aria-label="Permalink: 🙏 Acknowledgments" href="#-acknowledgments"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Born from a Reddit discussion about AI agent specialization. Thanks to the community for the feedback, requests, and inspiration.</p>
<p dir="auto">Special recognition to the 50+ Redditors who requested this within the first 12 hours - you proved there's demand for real, specialized AI agent systems.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">💬 Community</h2><a id="user-content--community" class="anchor" aria-label="Permalink: 💬 Community" href="#-community"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>GitHub Discussions</strong>: <a href="https://github.com/msitarzewski/agency-agents/discussions">Share your success stories</a></li>
<li><strong>Issues</strong>: <a href="https://github.com/msitarzewski/agency-agents/issues">Report bugs or request features</a></li>
<li><strong>Reddit</strong>: Join the conversation on r/ClaudeAI</li>
<li><strong>Twitter/X</strong>: Share with #TheAgency</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🚀 Get Started</h2><a id="user-content--get-started" class="anchor" aria-label="Permalink: 🚀 Get Started" href="#-get-started"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li><strong>Browse</strong> the agents above and find specialists for your needs</li>
<li><strong>Copy</strong> the agents to <code>~/.claude/agents/</code> for Claude Code integration</li>
<li><strong>Activate</strong> agents by referencing them in your Claude conversations</li>
<li><strong>Customize</strong> agent personalities and workflows for your specific needs</li>
<li><strong>Share</strong> your results and contribute back to the community</li>
</ol>
<hr>
<div align="center" dir="auto">
<p dir="auto"><strong>🎭 The Agency: Your AI Dream Team Awaits 🎭</strong></p>
<p dir="auto"><a href="https://github.com/msitarzewski/agency-agents">⭐ Star this repo</a> • <a href="https://github.com/msitarzewski/agency-agents/fork">🍴 Fork it</a> • <a href="https://github.com/msitarzewski/agency-agents/issues">🐛 Report an issue</a> • <a href="https://github.com/sponsors/msitarzewski">❤️ Sponsor</a></p>
<p dir="auto">Made with ❤️ by the community, for the community</p>
</div>
</article></div>]]></description>
      <link>https://github.com/msitarzewski/agency-agents</link>
      <guid>https://github.com/msitarzewski/agency-agents</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[RunanywhereAI/RCLI: Talk to your Mac, query your docs, no cloud required. On-device voice AI + RAG]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><p align="center" dir="auto">
  <a target="_blank" rel="noopener noreferrer" href="assets/rcli_waveform.gif"><img src="assets/rcli_waveform.gif" alt="RCLI Waveform" width="700" data-animated-image="" style="max-width: 100%;"></a>
  <br>
  <strong>Talk to your Mac, query your docs, no cloud required.</strong>
  <br><br>
  <a href="https://github.com/RunanywhereAI/RCLI"><img src="https://camo.githubusercontent.com/c9411b4859cd08394ca4e74a3613f6262cc87e7d86d920be0f988be76e66cad1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d6d61634f532d626c7565" alt="macOS" data-canonical-src="https://img.shields.io/badge/platform-macOS-blue" style="max-width: 100%;"></a>
  <a href="https://github.com/RunanywhereAI/RCLI"><img src="https://camo.githubusercontent.com/23ff775bfb5ea47f1b54ad2ed824037e402f19c2318f625bdbb8664a5defcd41/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636869702d4170706c655f53696c69636f6e2d626c61636b" alt="Apple Silicon" data-canonical-src="https://img.shields.io/badge/chip-Apple_Silicon-black" style="max-width: 100%;"></a>
  <a href="https://github.com/RunanywhereAI/RCLI"><img src="https://camo.githubusercontent.com/336d5e961adf1728bfb263a65e5be9fa3e791325b44d1e46e9b5b0dd628bf28a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f696e666572656e63652d3130302532355f6c6f63616c2d677265656e" alt="Local" data-canonical-src="https://img.shields.io/badge/inference-100%25_local-green" style="max-width: 100%;"></a>
  <a href="LICENSE"><img src="https://camo.githubusercontent.com/b8cadaa967891081f8f165695470689986c028821dd8a040132f6e661795dc0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c7565" alt="MIT" data-canonical-src="https://img.shields.io/badge/license-MIT-blue" style="max-width: 100%;"></a>
</p>
<p dir="auto"><strong>RCLI</strong> is an on-device voice AI for macOS. A complete STT + LLM + TTS pipeline running natively on Apple Silicon — 38 macOS actions via voice, local RAG over your documents, sub-200ms end-to-end latency. No cloud, no API keys.</p>
<p dir="auto">Powered by <a href="#metalrt-gpu-engine">MetalRT</a>, a proprietary GPU inference engine built by <a href="https://runanywhere.ai" rel="nofollow">RunAnywhere, Inc.</a> specifically for Apple Silicon.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Demo</h2><a id="user-content-demo" class="anchor" aria-label="Permalink: Demo" href="#demo"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<blockquote>
<p dir="auto">Real-time screen recordings on Apple Silicon — no cloud, no edits, no tricks.</p>
</blockquote>
<markdown-accessiblity-table><table>
<tbody><tr>
<td width="50%" align="center">
<strong>Voice Conversation</strong><br>
<em>Talk naturally — RCLI listens, understands, and responds on-device.</em><br><br>
<a href="https://youtu.be/qeardCENcV0" rel="nofollow">
<img src="assets/demos/demo1-voice-conversation.gif" alt="Voice Conversation Demo" width="100%" data-animated-image="" style="max-width: 100%;">
</a>
<br><sub>Click for full video with audio</sub>
</td>
<td width="50%" align="center">
<strong>App Control</strong><br>
<em>Control Spotify, adjust volume — 38 macOS actions by voice.</em><br><br>
<a href="https://youtu.be/eTYwkgNoaKg" rel="nofollow">
<img src="assets/demos/demo2-spotify-volume.gif" alt="App Control Demo" width="100%" data-animated-image="" style="max-width: 100%;">
</a>
<br><sub>Click for full video with audio</sub>
</td>
</tr>
<tr>
<td width="50%" align="center">
<strong>Models</strong><br>
<em>Browse models, hot-swap LLMs — all from the TUI.</em><br><br>
<a href="https://youtu.be/HD1aS37zIGE" rel="nofollow">
<img src="assets/demos/demo3-benchmarks.gif" alt="Models &amp; Benchmarks Demo" width="100%" data-animated-image="" style="max-width: 100%;">
</a>
<br><sub>Click for full video with audio</sub>
</td>
<td width="50%" align="center">
<strong>Document Intelligence (RAG)</strong><br>
<em>Ingest docs, ask questions by voice — ~4ms hybrid retrieval.</em><br><br>
<a href="https://youtu.be/8FEfbwS7cQ8" rel="nofollow">
<img src="assets/demos/demo4-rag-documents.gif" alt="RAG Demo" width="100%" data-animated-image="" style="max-width: 100%;">
</a>
<br><sub>Click for full video with audio</sub>
</td>
</tr>
</tbody></table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Install</h2><a id="user-content-install" class="anchor" aria-label="Permalink: Install" href="#install"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<blockquote>
<p dir="auto">[IMPORTANT]
<strong>Requires macOS 13+ on Apple Silicon. MetalRT engine requires M3 or later.</strong> M1/M2 Macs fall back to llama.cpp automatically.</p>
</blockquote>
<p dir="auto"><strong>One command:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="curl -fsSL https://raw.githubusercontent.com/RunanywhereAI/RCLI/main/install.sh | bash"><pre>curl -fsSL https://raw.githubusercontent.com/RunanywhereAI/RCLI/main/install.sh <span class="pl-k">|</span> bash</pre></div>
<p dir="auto"><strong>Or via Homebrew:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="brew tap RunanywhereAI/rcli https://github.com/RunanywhereAI/RCLI.git
brew install rcli
rcli setup          # required — downloads AI models (~1GB, one-time)"><pre>brew tap RunanywhereAI/rcli https://github.com/RunanywhereAI/RCLI.git
brew install rcli
rcli setup          <span class="pl-c"><span class="pl-c">#</span> required — downloads AI models (~1GB, one-time)</span></pre></div>
<p dir="auto"><strong>Upgrade to latest:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="brew update
brew upgrade rcli"><pre>brew update
brew upgrade rcli</pre></div>
<details>
<summary><strong>Troubleshooting: SHA256 mismatch or stale version</strong></summary>
<p dir="auto">If <code>brew install</code> or <code>brew upgrade</code> fails with a checksum error:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Force-refresh the tap to pick up the latest formula
cd $(brew --repo RunanywhereAI/rcli) &amp;&amp; git fetch origin &amp;&amp; git reset --hard origin/main
brew reinstall rcli"><pre><span class="pl-c"><span class="pl-c">#</span> Force-refresh the tap to pick up the latest formula</span>
<span class="pl-c1">cd</span> <span class="pl-s"><span class="pl-pds">$(</span>brew --repo RunanywhereAI/rcli<span class="pl-pds">)</span></span> <span class="pl-k">&amp;&amp;</span> git fetch origin <span class="pl-k">&amp;&amp;</span> git reset --hard origin/main
brew reinstall rcli</pre></div>
<p dir="auto">If that doesn't work, clean re-tap and clear the download cache:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="brew untap RunanywhereAI/rcli
rm -rf &quot;$(brew --cache)/downloads/&quot;*rcli*
brew tap RunanywhereAI/rcli https://github.com/RunanywhereAI/RCLI.git
brew install rcli
rcli setup"><pre>brew untap RunanywhereAI/rcli
rm -rf <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>brew --cache<span class="pl-pds">)</span></span>/downloads/<span class="pl-pds">"</span></span><span class="pl-k">*</span>rcli<span class="pl-k">*</span>
brew tap RunanywhereAI/rcli https://github.com/RunanywhereAI/RCLI.git
brew install rcli
rcli setup</pre></div>
</details>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Quick Start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick Start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="rcli                             # interactive TUI (push-to-talk + text)
rcli listen                      # continuous voice mode
rcli ask &quot;open Safari&quot;           # one-shot command
rcli ask &quot;play some jazz on Spotify&quot;
rcli metalrt                     # MetalRT GPU engine management
rcli llamacpp                    # llama.cpp engine management"><pre>rcli                             <span class="pl-c"><span class="pl-c">#</span> interactive TUI (push-to-talk + text)</span>
rcli listen                      <span class="pl-c"><span class="pl-c">#</span> continuous voice mode</span>
rcli ask <span class="pl-s"><span class="pl-pds">"</span>open Safari<span class="pl-pds">"</span></span>           <span class="pl-c"><span class="pl-c">#</span> one-shot command</span>
rcli ask <span class="pl-s"><span class="pl-pds">"</span>play some jazz on Spotify<span class="pl-pds">"</span></span>
rcli metalrt                     <span class="pl-c"><span class="pl-c">#</span> MetalRT GPU engine management</span>
rcli llamacpp                    <span class="pl-c"><span class="pl-c">#</span> llama.cpp engine management</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Benchmarks</h2><a id="user-content-benchmarks" class="anchor" aria-label="Permalink: Benchmarks" href="#benchmarks"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p align="center" dir="auto">
  <a target="_blank" rel="noopener noreferrer" href="assets/decode-vs-llamacpp.webp"><img src="assets/decode-vs-llamacpp.webp" alt="MetalRT vs llama.cpp decode speed" width="700" style="max-width: 100%;"></a>
  <br>
  <em>MetalRT decode throughput vs llama.cpp and Apple MLX on Apple M3 Max</em>
</p>
<p align="center" dir="auto">
  <a target="_blank" rel="noopener noreferrer" href="assets/rtf_comparison.webp"><img src="assets/rtf_comparison.webp" alt="STT and TTS real-time factor comparison" width="700" style="max-width: 100%;"></a>
  <br>
  <em>STT and TTS real-time factor — lower is better. MetalRT STT is 714x faster than real-time.</em>
</p>
<p dir="auto">For More info :</p>
<ul dir="auto">
<li><a href="https://www.runanywhere.ai/blog/metalrt-fastest-llm-decode-engine-apple-silicon" rel="nofollow">https://www.runanywhere.ai/blog/metalrt-fastest-llm-decode-engine-apple-silicon</a></li>
<li><a href="https://www.runanywhere.ai/blog/metalrt-speech-fastest-stt-tts-apple-silicon" rel="nofollow">https://www.runanywhere.ai/blog/metalrt-speech-fastest-stt-tts-apple-silicon</a></li>
<li><a href="https://www.runanywhere.ai/blog/fastvoice-on-device-voice-ai-pipeline-apple-silicon" rel="nofollow">https://www.runanywhere.ai/blog/fastvoice-on-device-voice-ai-pipeline-apple-silicon</a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Features</h2><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Voice Pipeline</h3><a id="user-content-voice-pipeline" class="anchor" aria-label="Permalink: Voice Pipeline" href="#voice-pipeline"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A full STT + LLM + TTS pipeline running on Metal GPU with three concurrent threads:</p>
<ul dir="auto">
<li><strong>VAD</strong> — Silero voice activity detection</li>
<li><strong>STT</strong> — Zipformer streaming + Whisper / Parakeet offline</li>
<li><strong>LLM</strong> — Qwen3 / LFM2 / Qwen3.5 with KV cache continuation and Flash Attention</li>
<li><strong>TTS</strong> — Double-buffered sentence-level synthesis (next sentence renders while current plays)</li>
<li><strong>Tool Calling</strong> — LLM-native tool call formats (Qwen3, LFM2, etc.)</li>
<li><strong>Multi-turn Memory</strong> — Sliding window conversation history with token-budget trimming</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">38 macOS Actions</h3><a id="user-content-38-macos-actions" class="anchor" aria-label="Permalink: 38 macOS Actions" href="#38-macos-actions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Control your Mac by voice or text. The LLM routes intent to actions executed locally via AppleScript and shell commands.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Category</th>
<th>Examples</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Productivity</strong></td>
<td><code>create_note</code>, <code>create_reminder</code>, <code>run_shortcut</code></td>
</tr>
<tr>
<td><strong>Communication</strong></td>
<td><code>send_message</code>, <code>facetime_call</code></td>
</tr>
<tr>
<td><strong>Media</strong></td>
<td><code>play_on_spotify</code>, <code>play_apple_music</code>, <code>play_pause</code>, <code>next_track</code>, <code>set_music_volume</code></td>
</tr>
<tr>
<td><strong>System</strong></td>
<td><code>open_app</code>, <code>quit_app</code>, <code>set_volume</code>, <code>toggle_dark_mode</code>, <code>screenshot</code>, <code>lock_screen</code></td>
</tr>
<tr>
<td><strong>Web</strong></td>
<td><code>search_web</code>, <code>search_youtube</code>, <code>open_url</code>, <code>open_maps</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">Run <code>rcli actions</code> to see all 38, or toggle them on/off in the TUI Actions panel.</p>
<blockquote>
<p dir="auto"><strong>Tip:</strong> If tool calling feels unreliable, press <strong>X</strong> in the TUI to clear the conversation and reset context. With small LLMs, accumulated context can degrade tool-calling accuracy — a fresh context often fixes it.</p>
</blockquote>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">RAG (Local Document Q&amp;A)</h3><a id="user-content-rag-local-document-qa" class="anchor" aria-label="Permalink: RAG (Local Document Q&amp;A)" href="#rag-local-document-qa"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Index local documents, query them by voice. Hybrid vector + BM25 retrieval with ~4ms latency over 5K+ chunks. Supports PDF, DOCX, and plain text.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="rcli rag ingest ~/Documents/notes
rcli ask --rag ~/Library/RCLI/index &quot;summarize the project plan&quot;"><pre>rcli rag ingest <span class="pl-k">~</span>/Documents/notes
rcli ask --rag <span class="pl-k">~</span>/Library/RCLI/index <span class="pl-s"><span class="pl-pds">"</span>summarize the project plan<span class="pl-pds">"</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Interactive TUI</h3><a id="user-content-interactive-tui" class="anchor" aria-label="Permalink: Interactive TUI" href="#interactive-tui"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A terminal dashboard with push-to-talk, live hardware monitoring, model management, and an actions browser.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Key</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>SPACE</strong></td>
<td>Push-to-talk</td>
</tr>
<tr>
<td><strong>M</strong></td>
<td>Models — browse, download, hot-swap LLM/STT/TTS</td>
</tr>
<tr>
<td><strong>A</strong></td>
<td>Actions — browse, enable/disable macOS actions</td>
</tr>
<tr>
<td><strong>R</strong></td>
<td>RAG — ingest documents</td>
</tr>
<tr>
<td><strong>X</strong></td>
<td>Clear conversation and reset context</td>
</tr>
<tr>
<td><strong>T</strong></td>
<td>Toggle tool call trace</td>
</tr>
<tr>
<td><strong>ESC</strong></td>
<td>Stop / close / quit</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">MetalRT GPU Engine</h2><a id="user-content-metalrt-gpu-engine" class="anchor" aria-label="Permalink: MetalRT GPU Engine" href="#metalrt-gpu-engine"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MetalRT is a high-performance GPU inference engine built by <a href="https://runanywhere.ai" rel="nofollow">RunAnywhere, Inc.</a> specifically for Apple Silicon. It delivers the fastest on-device inference for LLM, STT, and TTS — up to <strong>550 tok/s</strong> LLM throughput and sub-200ms end-to-end voice latency.</p>
<blockquote>
<p dir="auto"><strong>Apple M3 or later required.</strong> MetalRT uses Metal 3.1 GPU features available on M3, M3 Pro, M3 Max, M4, and later chips. M1/M2 support is coming soon. On M1/M2, RCLI automatically falls back to the open-source llama.cpp engine.</p>
</blockquote>
<p dir="auto">MetalRT is automatically installed during <code>rcli setup</code> (choose "MetalRT" or "Both"). Or install separately:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="rcli metalrt install
rcli metalrt status"><pre>rcli metalrt install
rcli metalrt status</pre></div>
<p dir="auto"><strong>Supported models:</strong> Qwen3 0.6B, Qwen3 4B, Llama 3.2 3B, LFM2.5 1.2B (LLM) · Whisper Tiny/Small/Medium (STT) · Kokoro 82M with 28 voices (TTS)</p>
<p dir="auto">MetalRT is distributed under a <a href="https://github.com/RunanywhereAI/metalrt-binaries/blob/main/LICENSE">proprietary license</a>. For licensing inquiries: <a href="mailto:founder@runanywhere.ai">founder@runanywhere.ai</a></p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Supported Models</h2><a id="user-content-supported-models" class="anchor" aria-label="Permalink: Supported Models" href="#supported-models"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">RCLI supports 20+ models across LLM, STT, TTS, VAD, and embeddings. All run locally on Apple Silicon. Use <code>rcli models</code> to browse, download, or switch.</p>
<p dir="auto"><strong>LLM:</strong> LFM2 1.2B (default), LFM2 350M, LFM2.5 1.2B, LFM2 2.6B, Qwen3 0.6B, Qwen3.5 0.8B/2B/4B, Qwen3 4B</p>
<p dir="auto"><strong>STT:</strong> Zipformer (streaming), Whisper base.en (offline, default), Parakeet TDT 0.6B (~1.9% WER)</p>
<p dir="auto"><strong>TTS:</strong> Piper Lessac/Amy, KittenTTS Nano, Matcha LJSpeech, Kokoro English/Multi-lang</p>
<p dir="auto"><strong>Default install</strong> (<code>rcli setup</code>): ~1GB — LFM2 1.2B + Whisper + Piper + Silero VAD + Snowflake embeddings.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="rcli models                  # interactive model management
rcli upgrade-llm             # guided LLM upgrade
rcli voices                  # browse and switch TTS voices
rcli cleanup                 # remove unused models"><pre>rcli models                  <span class="pl-c"><span class="pl-c">#</span> interactive model management</span>
rcli upgrade-llm             <span class="pl-c"><span class="pl-c">#</span> guided LLM upgrade</span>
rcli voices                  <span class="pl-c"><span class="pl-c">#</span> browse and switch TTS voices</span>
rcli cleanup                 <span class="pl-c"><span class="pl-c">#</span> remove unused models</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Build from Source</h2><a id="user-content-build-from-source" class="anchor" aria-label="Permalink: Build from Source" href="#build-from-source"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">CPU-only build using llama.cpp + sherpa-onnx (no MetalRT):</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/RunanywhereAI/RCLI.git &amp;&amp; cd RCLI
bash scripts/setup.sh
bash scripts/download_models.sh
mkdir -p build &amp;&amp; cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(sysctl -n hw.ncpu)
./rcli"><pre>git clone https://github.com/RunanywhereAI/RCLI.git <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">cd</span> RCLI
bash scripts/setup.sh
bash scripts/download_models.sh
mkdir -p build <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">cd</span> build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build <span class="pl-c1">.</span> -j<span class="pl-s"><span class="pl-pds">$(</span>sysctl -n hw.ncpu<span class="pl-pds">)</span></span>
./rcli</pre></div>
<p dir="auto">All dependencies are vendored or CMake-fetched. Requires CMake 3.15+ and Apple Clang (C++17).</p>
<details>
<summary><strong>CLI Reference</strong></summary>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="rcli                          Interactive TUI (push-to-talk + text + trace)
rcli listen                   Continuous voice mode
rcli ask &lt;text&gt;               One-shot text command
rcli actions [name]           List actions or show detail
rcli rag ingest &lt;dir&gt;         Index documents for RAG
rcli rag query &lt;text&gt;         Query indexed documents
rcli models [llm|stt|tts]    Manage AI models
rcli voices                   Manage TTS voices
rcli metalrt                  MetalRT GPU engine management
rcli llamacpp                 llama.cpp engine management
rcli setup                    Download default models
rcli info                     Show engine and model info

Options:
  --models &lt;dir&gt;      Models directory (default: ~/Library/RCLI/models)
  --rag &lt;index&gt;       Load RAG index for document-grounded answers
  --gpu-layers &lt;n&gt;    GPU layers for LLM (default: 99 = all)
  --ctx-size &lt;n&gt;      LLM context size (default: 4096)
  --no-speak          Text output only (no TTS)
  --verbose, -v       Debug logs"><pre class="notranslate"><code>rcli                          Interactive TUI (push-to-talk + text + trace)
rcli listen                   Continuous voice mode
rcli ask &lt;text&gt;               One-shot text command
rcli actions [name]           List actions or show detail
rcli rag ingest &lt;dir&gt;         Index documents for RAG
rcli rag query &lt;text&gt;         Query indexed documents
rcli models [llm|stt|tts]    Manage AI models
rcli voices                   Manage TTS voices
rcli metalrt                  MetalRT GPU engine management
rcli llamacpp                 llama.cpp engine management
rcli setup                    Download default models
rcli info                     Show engine and model info

Options:
  --models &lt;dir&gt;      Models directory (default: ~/Library/RCLI/models)
  --rag &lt;index&gt;       Load RAG index for document-grounded answers
  --gpu-layers &lt;n&gt;    GPU layers for LLM (default: 99 = all)
  --ctx-size &lt;n&gt;      LLM context size (default: 4096)
  --no-speak          Text output only (no TTS)
  --verbose, -v       Debug logs
</code></pre></div>
</details>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Contributions welcome. See <a href="CONTRIBUTING.md">CONTRIBUTING.md</a> for build instructions and how to add new actions, models, or voices.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">RCLI is open source under the <a href="LICENSE">MIT License</a>.</p>
<p dir="auto">MetalRT is proprietary software by <a href="https://runanywhere.ai" rel="nofollow">RunAnywhere, Inc.</a>, distributed under a separate <a href="https://github.com/RunanywhereAI/metalrt-binaries/blob/main/LICENSE">license</a>.</p>
<p align="center" dir="auto">
  Built by <a href="https://www.runanywhere.ai" rel="nofollow">RunAnywhere, Inc.</a>
</p>
</article></div>]]></description>
      <link>https://github.com/RunanywhereAI/rcli</link>
      <guid>https://github.com/RunanywhereAI/rcli</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Top 100 Gen AI Consumer Apps — 6th Edition / Andreessen Horowitz]]></title>
      <description><![CDATA[<p>Three years ago, we published the <a href="https://a16z.com/how-are-consumers-using-generative-ai/">first edition of this list</a> with a simple goal: identify which generative AI products were actually getting used by mainstream consumers. At the time, the distinction between “AI-first” companies and everything else was clear. ChatGPT, Midjourney, and Character.AI were purpose-built around foundation models. The rest of the software world was still figuring out what to do with the technology.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2.png"><img class="alignnone wp-image-382423 size-full" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2.png" alt="" width="2000" height="1267" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2-300x190.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2-1024x649.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2-768x487.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2-1536x973.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Web-Top-50-List-v2-400x253.png 400w" sizes="(max-width: 2000px) 100vw, 2000px" /></a></p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List.jpg"><img class="alignnone size-full wp-image-382363" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List.jpg" alt="" width="2000" height="1267" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List.jpg 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List-300x190.jpg 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List-1024x649.jpg 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List-768x487.jpg 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List-1536x973.jpg 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Top-Gen-AI-Apps-Top-50-List-400x253.jpg 400w" sizes="(max-width: 2000px) 100vw, 2000px" /></a></p><p>That distinction no longer holds. CapCut, a video editor with 736 million monthly active mobile users, relies on AI for its most popular features — background removal, AI effects, auto-captions, and text-to-video generation. Canva has built its entire growth engine around its Magic Suite of AI tools. Notion has seen its paid AI attach rate surge from 20% to over 50% in a single year — AI features <a href="https://www.forbes.com/sites/annatong/2025/12/15/notion-kicks-off-employee-share-sale-at-11-billion-valuation-as-ai-accelerates-its-growth/" target="_blank" rel="noopener noreferrer">now account for</a> roughly half of the company’s ARR.</p><p>From this edition onward, we’re broadening the aperture to include any consumer product where generative AI has become a core part of the experience — including CapCut, Canva, Notion, Picsart, Freepik, and Grammarly. The result is what we believe is a more accurate picture of how people actually use AI, though the bulk of the top products continue to be AI-native.<br /><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps.png"><img class="aligncenter size-full wp-image-382379" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps.png" alt="A chart titled: Return of the Legacy Apps" width="2000" height="1789" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps-300x268.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps-1024x916.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps-768x687.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps-1536x1374.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Return-of-the-Legacy-Apps-400x358.png 400w" sizes="(max-width: 2000px) 100vw, 2000px" /></a>As always, our web ranking is based on unique monthly visits, per SimilarWeb as of January 2026. Mobile apps are ranked by monthly active users, per Sensor Tower as of January 2026. Here are our top takeaways:</p><h2>1. ChatGPT leads but the race for the “default AI” is on</h2><p>ChatGPT is still far and away the largest consumer AI product. On web, it is 2.7x larger than the #2, Gemini (measured by monthly traffic) — and on mobile, it is 2.5x larger (measured by monthly active users). ChatGPT has seen weekly active users grow by 500 million people over the past year to <a href="https://techcrunch.com/2026/02/27/chatgpt-reaches-900m-weekly-active-users/?utm_source=dlvr.it&amp;utm_medium=twitter" target="_blank" rel="noopener noreferrer">900 million</a> today. This is especially impressive given growth is difficult to maintain at scale — over 10% of the global population now utilizes ChatGPT every week.<br /><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer.png"><img class="aligncenter size-full wp-image-382386" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer.png" alt="A chart titled: Who is Winning the Mainstream Consumer." width="2000" height="1963" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer-300x294.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer-1024x1005.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer-768x754.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer-1536x1508.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Who-is-winning-the-mainstream-consumer-400x393.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2.png"><img class="aligncenter size-full wp-image-382392" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2.png" alt="A chart titled: Chat GPT vs Gemini Time Spent" width="2000" height="1846" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2-300x277.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2-1024x945.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2-768x709.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2-1536x1418.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Chat-GPT-vs-Gemini-Time-Spent-v2-400x369.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>But we’re starting to see the category widening, with other horizontal platforms picking up steam for specific use cases. Both Gemini and Claude have seen an acceleration in their U.S. paid subscriber growth over the past year (though still dwarfed by ChatGPT — which is 8x larger than Claude and 4x larger than Gemini on this metric). Per Yipit Data, as of January 2026, Claude was growing paid subscribers by over 200% YoY — while Gemini was growing 258%. And, we’re seeing increasing multi-tenanting behavior — with roughly 20% of weekly ChatGPT web users also using Gemini in a given week.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead.png"><img class="aligncenter size-full wp-image-382374" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead.png" alt="A chart titled: ChatGPT has the Lead in Consumer Subscriptions" width="2000" height="1971" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead-300x296.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead-1024x1009.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead-768x757.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead-1536x1514.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-has-the-lead-400x394.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>What happened? The competitors shipped. Google crushed its creative models — Nano Banana generated 200 million images and brought 10 million new users to Gemini in its first week, and Veo 3 was widely regarded as the breakthrough moment for AI video. Anthropic doubled down on the prosumer with Cowork, Claude in Chrome, plug-ins to Excel and Powerpoint, and — most notably — Claude Code.</p><p>The race matters not just for who leads today but for who becomes structurally difficult to displace. Context compounds: the more an LLM knows about you, the better results it can provide and the more you use it. Early data suggests that sessions per user per month are climbing for Gemini on web, though they’re still 1.3x higher on ChatGPT — and on mobile, ChatGPT dominates with 2.2x higher sessions per user per month. Both companies show best-in-class consumer paid subscriber retention in the U.S., per Yipit Data.<br /><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing.png"><img class="aligncenter size-full wp-image-382380" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing.png" alt="A chart titled: Sessions per month on Gemini are climbing... but OpenAI still leads." width="2000" height="1623" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing-300x243.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing-1024x831.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing-768x623.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing-1536x1246.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sessions-per-month-on-Gemini-are-climbing-400x325.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention.png"><img class="aligncenter size-full wp-image-382388" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention.png" alt="A chart titled: ChatGPT and Gemini have unparalleled retention." width="2000" height="2053" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention-292x300.png 292w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention-998x1024.png 998w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention-768x788.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention-1496x1536.png 1496w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention-1995x2048.png 1995w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/ChatGPT-and-Gemini-Have-Unparalleled-Retention-390x400.png 390w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>The next layer of lock-in is the app store. ChatGPT and Claude have both launched connector ecosystems — GPTs and Apps for ChatGPT, MCP integrations and Connectors for Claude — that let users build workflows on top of the assistant. Once a user has configured their AI to talk to their calendar, email, and CRM, switching costs rise dramatically. Developers may concentrate their efforts on the platforms that attract the most users, creating the same kind of flywheel that defined earlier platform wars.</p><p>We’re already starting to see where each platform is heading. Sam Altman has previously said OpenAI wants to “bring AI to billions of people who can’t pay for subscriptions,” which is why they’ve launched ads — and he’s stated that OpenAI will launch a “Sign in with ChatGPT” identity layer, positioning the assistant as the default interface between consumers and the internet. The ambition is to make ChatGPT the starting point for everything: shopping, booking, browsing, health, and daily life.</p><p>The app directories already reflect this. As of late February, ChatGPT’s includes 220 apps across 13 categories. Claude has ~160 curated connectors plus ~50 community-built MCP servers. But the two share just 41 apps in common — roughly 11% of the combined catalog — and those 41 are almost entirely the horizontal productivity stack everyone needs: Slack, Notion, Figma, Gmail, Google Calendar, HubSpot, Stripe.</p><p>Beyond that core, the platforms diverge almost completely. ChatGPT has 85+ apps across Travel, Shopping, Food, Health &amp; Wellness, Lifestyle, and Entertainment — categories where Claude has virtually zero. These are consumer transaction categories: booking flights on Expedia, ordering groceries through Instacart, browsing listings on Zillow, tracking nutrition on MyFitnessPal. It’s the most aggressive play any AI company has made to become a consumer super-app. Claude’s exclusive integrations skew toward the professional: financial data terminals (PitchBook, FactSet, Moody’s, MSCI), developer infrastructure (Sentry, Supabase, Snowflake, Databricks), science and medical tools (PubMed, Clinical Trials, Benchling), and a growing open-source MCP community that has no ChatGPT equivalent.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom.png"><img class="aligncenter size-full wp-image-382377" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom.png" alt="" width="2000" height="2042" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom-294x300.png 294w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom-1003x1024.png 1003w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom-768x784.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom-1504x1536.png 1504w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Let-a-Thousand-MCP-Servers-Bloom-392x400.png 392w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>Anthropic appears to be focused on the AI power users (developers, knowledge workers, etc.) These users are more willing and able to pay for higher cost, direct subscriptions now. While ChatGPT has products catered to the same audience (ex. Codex, Frontier), they have also indicated a desire to be the platform for the true mainstream user — which may open up more avenues for monetization as the base continues to grow. They are already <a href="https://openai.com/index/testing-ads-in-chatgpt/" target="_blank" rel="noopener noreferrer">testing ads</a>, and a take rate on transactions would also be a natural expansion.</p><p>If the AI assistant becomes not just a chat window but an operating environment, this race may end up looking less like the search wars — where one player took 90% of the market — and more like the mobile OS wars, where two platforms with very different philosophies both built trillion-dollar ecosystems.</p><h2>2. Global usage is splintering by product</h2><p>Geographically, the AI market is splintering into three distinct ecosystems, and the gaps between them are widening.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country.png"><img class="aligncenter size-full wp-image-382371" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country.png" alt="A chart titled: AI Chatbot Market Share by Country" width="2000" height="1678" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country-300x252.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country-1024x859.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country-768x644.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country-1536x1289.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/AI-Chatbot-Market-Share-by-Country-400x336.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>The Western AI tools continue to share a remarkably similar user base. ChatGPT, Claude, Gemini, and Perplexity all draw their top markets from the same pool: the US, India, Brazil, the UK, and Indonesia, in varying order. None has meaningful usage in China or Russia. This is a function of policy — Western tech sanctions have restricted access to US AI tools in Russia since 2022, and China requires AI providers to register, host data onshore, and comply with censorship rules.</p><p>DeepSeek is the only product that bridges the divide. Its traffic splits across China (33.5%), Russia (7.1%), and the US (6.6%) on web, with a similar pattern on mobile. China is also a heavy user of Bytedance’s Doubao and homegrown Kimi.</p><p>Russia, which barely registered as a distinct market in our earlier editions, has emerged as a third pole with the second highest rate of Deepseek saturation. Yandex Browser, which integrates the Alice AI assistant, reached 71 million MAU — making it a top ten mobile AI product globally. Sber’s GigaChat debuted on our web list. The pattern mirrors what happened in China, but compressed: sanctions created the gap, and local products filled it within two years.</p><p>To look at AI adoption on a per capita basis, we built a simple index combining web visits per capita and mobile MAU per capita across the products on our lists, scored from 0 to 100. The results reframe the geographic picture. Singapore ranks first, followed by the UAE, Hong Kong, and South Korea. The United States — the country that produced most of these products — ranks 20th.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening.png"><img class="aligncenter size-full wp-image-382385" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening.png" alt="A map titled: Where in the world is AI adoption happening?" width="2000" height="1802" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening-300x270.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening-1024x923.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening-768x692.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening-1536x1384.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Where-in-the-world-is-AI-adoption-happening-400x360.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a></p><h2>3. Creative tools make moves</h2><p>Midjourney, DALL-E, and Stable Diffusion were the products that introduced most early adopters to generative AI — all three were released pre-ChatGPT. Image generation tools not only dominated creative tools (video and audio generation came later), but reigned supreme in our first three list versions of this list. The category has since evolved significantly.</p><p>In our first edition in September 2023, seven of the nine creative tools on the web list were image generators. Three years later, only three image generators remain — but seven creative tools still make the list. The difference is what fills the gap: video, music, and voice products have taken the slots that image generation vacated.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates.png"><img class="aligncenter size-full wp-image-382376" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates.png" alt="A chart titled: Image generation still dominates in creative tools but usage is migrating to model platorms." width="2000" height="2128" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates-282x300.png 282w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates-962x1024.png 962w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates-768x817.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates-1444x1536.png 1444w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates-1925x2048.png 1925w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Image-generation-still-dominates-376x400.png 376w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>The image story is one of bundling. As the native image models within ChatGPT (GPT Image 1.5) and Gemini (nano banana) improved, the bar for standalone image products rose sharply. On our very first edition of this list, Midjourney ranked in the top 10 — it’s since fallen to #46. The products that remain — Leonardo, Ideogram, CivitAI — tend to serve specific creative communities with opinionated features rather than competing on general-purpose generation.</p><p>Video generation saw the most movement this edition. Kling AI, Hailuo, and Pixverse have all built real traction, with Chinese-developed models consistently leading in output quality — we would not be surprised to see Seedance 2.0-based applications on the next list. Veo 3 was the first US model to close that gap, and has driven traffic to Google Labs (which rose from #36 to #25 in the ranks).</p><p>What’s missing? Sora. OpenAI launched the 2.0 version of its flagship video model as a standalone app in September 2025 — users were able to upload their digital likeness as a Cameo, and generate videos featuring real people. Sora spent 20 days at the top of the U.S. App Store and reached <a href="https://www.cnbc.com/2025/10/09/openais-sora-downloads.html" target="_blank" rel="noopener noreferrer">1 million downloads</a> faster than ChatGPT. Since then, downloads have decreased, as Sora stopped virally exploding as a social app (no one has yet cracked AI x social) — preventing it from making the mobile list for this edition. But, SensorTower still counts upwards of 3 million daily active Sora users on mobile, as AI video creators continue to leverage the model even if they cross-publish outputs elsewhere.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU.png"><img class="aligncenter size-full wp-image-382381" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU.png" alt="A chart titled: Sora's daily active users continue to climb" width="2000" height="1867" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU-300x280.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU-1024x956.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU-768x717.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU-1536x1434.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Sora-Global-DAU-400x373.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>Music and voice have been more defensible. Suno (#15) retained its rank from the last version of the list. ElevenLabs has appeared on every edition since September 2023; its capabilities — voice cloning, dubbing, audio production — remain specialized enough that they haven’t been replicated as a checkbox feature.</p><p>The pattern: where the model giants and incumbents like Google and OpenAI have focused their creative efforts (image, increasingly video), standalone traffic compresses — though there is still room for more opinionated and perhaps more highly monetized products that serve users beyond the mainstream. Where they haven’t (music, voice), there’s more room.</p><h2>4. Agents are here</h2><p>The shift toward agentic AI didn’t start this edition — it started last edition, with vibe coding. When Lovable, Cursor, and Bolt appeared on our March 2025 list, they represented something new: AI products that didn’t just answer questions or generate media, but built things on the user’s behalf. That was agentic behavior, scoped to a single vertical.</p><p>Vibe coding has proved retentive among a technical (and semi-technical) audience — with Replit and Lovable represented on this edition, as well as Claude Code (via Claude). There’s more growth to come, as the trend has not yet cracked the true mainstream. Traffic across the top five vibe coding platforms has continued, though slowed from the initial explosion — though revenue continues to rise for many of these products as developers and teams use them more intensely.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3.png"><img class="aligncenter size-full wp-image-382395" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3.png" alt="A chart titled: Vibe coding revenue growth has continued" width="2000" height="1974" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3-300x296.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3-1024x1011.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3-768x758.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3-1536x1516.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Vibe-coding-revenue-growth-has-continued-v3-400x395.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>More recently, horizontal agents have started to emerge. In January 2026, an open-source project called OpenClaw went from a solo developer’s side project to 68,000 GitHub stars and mainstream coverage in a matter of weeks. Built by Austrian developer Peter Steinberger, OpenClaw is a locally run AI agent that connects to your messaging apps and executes multi-step tasks on your behalf.</p><p>If ChatGPT was the moment consumers discovered AI could talk, OpenClaw may be the moment they discovered AI could act. The product took off in the developer community — if our analysis was pushed to February (not January), OpenClaw would have ranked in the top 30 of our web list.</p><p>And yet, OpenClaw is not (yet!) consumer-grade — it requires knowledge of Terminal to set up and maintain. OpenClaw has continued to pick up traction among technical users, and in early March became the most-starred project on Github — surpassing both React and Linux. However, the product has not yet “graduated” to the true mainstream user — at least, as measured by new visits to the OpenClaw setup web domain (which have been fairly flat). The product was acquired by OpenAI in February 2026, which perhaps indicates the possibility of an even more accessible version of OpenClaw coming soon.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity.png"><img class="aligncenter size-full wp-image-382382" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity.png" alt="A chart titled: The Claw Singularity was written in the (Github) stars" width="2000" height="1914" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity-300x287.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity-1024x980.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity-768x735.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity-1536x1470.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/The-Claw-Singularity-400x383.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a></p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2.png"><img class="aligncenter size-full wp-image-382394" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2.png" alt="A chart titled: OpenClaw developer usage." width="2000" height="1920" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2-300x288.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2-1024x983.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2-768x737.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2-1536x1475.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/OpenClaw-Developer-Usage-v2-400x384.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>OpenClaw isn’t the only horizontal agent on the list. Both Manus and Genspark made the ranks — each platform allows consumers to hand over open-ended tasks (research, spreadsheet analysis, slide generation), and AI will handle the workflow end-to-end. This is Manus’s second time on the list, and since it debuted it was acquired by Meta in December 2025 for an estimated $2 billion. Genspark debuts on this edition — the company raised a $300M Series B earlier this year, and announced a $100M <a href="https://www.axios.com/pro/enterprise-software-deals/2026/01/21/genspark-funding-100-million-arr-genai" target="_blank" rel="noopener noreferrer">revenue run rate</a>.</p><p>On mobile, consumers generally interact with agents via text — not via mobile apps. At setup, users connect OpenClaw to platforms like WhatsApp, Telegram, and Signal; users message it like they’d message a friend, and it executes tasks in the background. Other products like <a href="https://poke.com/" target="_blank" rel="noopener noreferrer">Poke</a> similarly provide an agentic experience directly via SMS.</p><p>These products will compete with the agentic capabilities of the general LLM assistants that consumers use every day — ChatGPT, Claude, and Gemini. As they build their own connective tissues with Connectors and apps, will consumers use one of these products as their primary agent? The next six months will give us a good picture.</p><h2>5. AI beyond the browser or app</h2><p>Every prior edition of this list has ranked AI products by two metrics: web visits and mobile MAU. But a new class of AI products is emerging that these rankings cannot capture. Some of the most significant consumer AI growth of the past year happened in products that don’t register in either metric.</p><p>The most visible shift is the browser itself becoming an AI product. In the past nine months, OpenAI launched Atlas (a browser with ChatGPT built into every page), Perplexity shipped Comet, and the Browser Company (since acquired by Atlassian) launched Dia. Data from Yipit shows that Perplexity’s Comet has made the biggest dent in the market (in terms of visits to the download page), though no AI browser has seen accelerating growth.</p><p>Other AI giants are choosing to add AI to an existing browser, versus launching an AI browser as a standalone product. Google added Gemini to Chrome and released <a href="https://labs.google/disco" target="_blank" rel="noopener noreferrer">Disco</a> in beta-testing, which dynamically generates web apps based on a user’s browser tab. Anthropic released Claude in Chrome, which can connect to a user’s Claude or Claude Code session to drive action on the web.</p><p><a href="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet.png"><img class="aligncenter size-full wp-image-382384" src="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet.png" alt="A chart titled: Web Visits to Comet Download Page" width="2000" height="1926" srcset="https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet.png 2000w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet-300x289.png 300w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet-1024x986.png 1024w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet-768x740.png 768w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet-1536x1479.png 1536w, https://d1lamhf6l6yk6d.cloudfront.net/uploads/2026/03/Web-Visits-to-Comet-400x385.png 400w" sizes="auto, (max-width: 2000px) 100vw, 2000px" /></a>Desktop-native AI tools have seen even more dramatic growth, especially for developers. Claude Code — a command-line agent for developers — reached a $1 billion annualized revenue run rate in just six months. OpenAI shipped a standalone Codex app for Mac, with the <a href="https://openai.com/index/scaling-ai-for-everyone/" target="_blank" rel="noopener noreferrer">company reporting</a> total Codex weekly active users of 2 million as of early March, growing 25% weekly. And, Cursor retained its spot on our top 50 web list.</p><p>For pure consumers, the most common standalone AI desktop applications are voice-related. Notetakers like Fireflies, Fathom, Otter, TL;DV, and Granola, have reached users via PLG and increasingly saturated enterprises — with a combined 20M visitors combined across the top five players. Workspace apps like Notion (debuting on this list), have also increasingly integrated AI via notetakers, research agents, and even task automation.</p><p>Finally, AI is increasingly embedded in the tools people already use. Anthropic launched Claude in Excel and Claude in PowerPoint. OpenAI launched ChatGPT for Excel. Google has deepened Gemini’s integration across Workspace — Docs, Sheets, Gmail, and Meet all now have native AI capabilities. Google also launched Personal Intelligence in January 2026, connecting Gemini to Gmail, Google Photos, YouTube, and Search — so the assistant can reference your hotel booking, your purchase history, your photo library, and your watch habits without being told.</p><p>The implication for this list: our rankings increasingly undercount the AI products people use most. A developer who spends eight hours a day in Claude Code and a knowledge worker who dictates every email through Wispr are heavy AI users who barely register in web traffic data. As AI moves from a destination to a feature, our methodology will need to shift.</p><h2>Links: Top 50 Gen AI Consumer Web Products</h2><div class="md:columns-3 columns mt-7 mb-7 [&amp;.columns_p+p]:mt-3"><p><a href="http://adot.ai" target="_blank" rel="noopener noreferrer">Adot AI</a><br /><a href="http://candy.ai" target="_blank" rel="noopener noreferrer">Candy Network</a><br /><a href="http://canva.com" target="_blank" rel="noopener noreferrer">Canva</a><br /><a href="http://capcut.com" target="_blank" rel="noopener noreferrer">Capcut</a><br /><a href="http://character.ai" target="_blank" rel="noopener noreferrer">Character.ai</a><br /><a href="http://chatgpt.com" target="_blank" rel="noopener noreferrer">ChatGPT</a><br /><a href="http://civitai.com" target="_blank" rel="noopener noreferrer">Civitai</a><br /><a href="http://claude.ai" target="_blank" rel="noopener noreferrer">Claude</a><br /><a href="http://crushon.ai" target="_blank" rel="noopener noreferrer">CrushOn</a><br /><a href="http://cursor.com/" target="_blank" rel="noopener noreferrer">Cursor</a><br /><a href="http://cutout.pro" target="_blank" rel="noopener noreferrer">Cutout</a><br /><a href="http://deepseek.com" target="_blank" rel="noopener noreferrer">Deepseek</a><br /><a href="http://doubao.com" target="_blank" rel="noopener noreferrer">Doubao</a><br /><a href="http://elevenlabs.io" target="_blank" rel="noopener noreferrer">ElevenLabs</a><br /><a href="http://freepik.com" target="_blank" rel="noopener noreferrer">Freepik</a><br /><a href="https://gamma.app/" target="_blank" rel="noopener noreferrer">Gamma</a><br /><a href="http://gemini.google.com" target="_blank" rel="noopener noreferrer">Gemini</a><br /><a href="http://aistudio.google.com" target="_blank" rel="noopener noreferrer">Google AI Studio</a><br /><a href="https://labs.google/" target="_blank" rel="noopener noreferrer">Google Labs</a><br /><a href="http://genspark.ai" target="_blank" rel="noopener noreferrer">Genspark</a><br /><a href="https://giga.chat/" target="_blank" rel="noopener noreferrer">GigaChat</a><br /><a href="http://grammarly.com" target="_blank" rel="noopener noreferrer">Grammarly</a><br /><a href="http://grok.com" target="_blank" rel="noopener noreferrer">Grok</a><br /><a href="http://higgsfield.ai" target="_blank" rel="noopener noreferrer">Higgsfield</a><br /><a href="http://huggingface.co" target="_blank" rel="noopener noreferrer">Hugging Face</a><br /><a href="http://janitorai.com" target="_blank" rel="noopener noreferrer">Janitor AI</a><br /><a href="http://kimi.com" target="_blank" rel="noopener noreferrer">Kimi</a><br /><a href="http://klingai.com" target="_blank" rel="noopener noreferrer">Kling AI</a><br /><a href="http://lmarena.ai" target="_blank" rel="noopener noreferrer">Arena</a><br /><a href="https://lovable.dev/" target="_blank" rel="noopener noreferrer">Lovable</a><br /><a href="http://manus.im" target="_blank" rel="noopener noreferrer">Manus</a><br /><a href="http://meta.ai" target="_blank" rel="noopener noreferrer">Meta AI</a><br /><a href="http://midjourney.com" target="_blank" rel="noopener noreferrer">Midjourney</a><br /><a href="https://notebooklm.google/" target="_blank" rel="noopener noreferrer">NotebookLM</a><br /><a href="http://notion.so" target="_blank" rel="noopener noreferrer">Notion</a><br /><a href="http://ourdream.ai" target="_blank" rel="noopener noreferrer">Ourdream.ai</a><br /><a href="http://perplexity.ai" target="_blank" rel="noopener noreferrer">Perplexity</a><br /><a href="http://photoroom.com" target="_blank" rel="noopener noreferrer">Photoroom</a><br /><a href="http://pixelcut.ai" target="_blank" rel="noopener noreferrer">Pixelcut</a><br /><a href="http://poe.com" target="_blank" rel="noopener noreferrer">Poe</a><br /><a href="http://polybuzz.ai" target="_blank" rel="noopener noreferrer">Polybuzz</a><br /><a href="http://quark.cn" target="_blank" rel="noopener noreferrer">Quark</a><br /><a href="http://quillbot.com" target="_blank" rel="noopener noreferrer">Quillbot</a><br /><a href="http://qwen.ai" target="_blank" rel="noopener noreferrer">Qwen</a><br /><a href="http://remove.bg" target="_blank" rel="noopener noreferrer">Remove.bg</a><br /><a href="http://seaart.ai" target="_blank" rel="noopener noreferrer">SeaArt</a><br /><a href="http://spicychat.ai" target="_blank" rel="noopener noreferrer">Spicychat</a><br /><a href="http://suno.com" target="_blank" rel="noopener noreferrer">Suno</a><br /><a href="http://turboscribe.ai" target="_blank" rel="noopener noreferrer">Turboscribe</a><br /><a href="http://veed.io" target="_blank" rel="noopener noreferrer">Veed</a></p></div><h2>Links: Top 50 Gen AI Consumer Mobile Apps</h2><div class="md:columns-3 columns mt-7 mb-7 [&amp;.columns_p+p]:mt-3"><p><a href="https://apps.apple.com/us/app/ai-gallery/id1665221706" target="_blank" rel="noopener noreferrer">AI Gallery</a><br /><a href="https://apps.apple.com/us/app/ai-mirror-ai-photo-editor/id6444888896" target="_blank" rel="noopener noreferrer">AI Mirror</a><br /><a href="https://apps.apple.com/us/app/b612-ai-photo-video-editor/id904209370" target="_blank" rel="noopener noreferrer">B612</a><br /><a href="https://apps.apple.com/cn/app/%E7%99%BE%E5%BA%A6-ai%E6%99%BA%E8%83%BD%E6%90%9C%E7%B4%A2/id382201985" target="_blank" rel="noopener noreferrer">Baidu AI Search</a><br /><a href="https://apps.apple.com/us/app/beautycam-ai-photo-editor/id592331499" target="_blank" rel="noopener noreferrer">BeautyCam</a><br /><a href="https://apps.apple.com/us/app/beautyplus-selfie-photo-editor/id622434129" target="_blank" rel="noopener noreferrer">BeautyPlus</a><br /><a href="https://apps.apple.com/us/app/brainly-ai-homework-helper/id745089947" target="_blank" rel="noopener noreferrer">Brainly</a><br /><a href="https://apps.apple.com/us/app/canva-ai-photo-video-editor/id897446215" target="_blank" rel="noopener noreferrer">Canva</a><br /><a href="https://apps.apple.com/us/app/capcut-photo-video-editor/id1500855883" target="_blank" rel="noopener noreferrer">Capcut</a><br /><a href="https://apps.apple.com/us/app/character-ai-chat-talk-text/id1671705818" target="_blank" rel="noopener noreferrer">Character.ai</a><br /><a href="https://apps.apple.com/us/app/chatgpt/id6448311069" target="_blank" rel="noopener noreferrer">ChatGPT</a><br /><a href="https://play.google.com/store/apps/details?id=com.larus.wolf" target="_blank" rel="noopener noreferrer">CiCi</a><br /><a href="https://apps.apple.com/us/app/microsoft-copilot/id6472538445" target="_blank" rel="noopener noreferrer">Copilot</a><br /><a href="https://apps.apple.com/us/app/deepseek-ai-assistant/id6737597349" target="_blank" rel="noopener noreferrer">Deepseek</a><br /><a href="https://apps.apple.com/cn/app/%E8%B1%86%E5%8C%85-%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8%E6%97%97%E4%B8%8Bai%E5%8A%A9%E6%89%8B/id6459478672" target="_blank" rel="noopener noreferrer">Doubao</a><br /><a href="https://apps.apple.com/us/app/edits-video-editor/id6738967378" target="_blank" rel="noopener noreferrer">Edits</a><br /><a href="https://apps.apple.com/us/app/faceapp-perfect-face-editor/id1180884341" target="_blank" rel="noopener noreferrer">FaceApp</a><br /><a href="https://apps.apple.com/us/app/facemoji-ai-emoji-keyboard/id1103138272" target="_blank" rel="noopener noreferrer">Facemoji</a><br /><a href="https://apps.apple.com/za/app/gauth-ai-study-companion/id1542571008" target="_blank" rel="noopener noreferrer">Gauth</a><br /><a href="https://apps.apple.com/us/app/google-gemini/id6477489729" target="_blank" rel="noopener noreferrer">Gemini</a><br /><a href="https://apps.apple.com/us/app/grok/id6670324846" target="_blank" rel="noopener noreferrer">Grok</a><br /><a href="https://play.google.com/store/apps/details?id=com.zaz.translate&amp;hl=en_US" target="_blank" rel="noopener noreferrer">Hi Translate</a><br /><a href="https://apps.apple.com/us/app/hypic-photo-editor-ai-art/id1644042837" target="_blank" rel="noopener noreferrer">Hypic</a><br /><a href="https://apps.apple.com/us/app/speak-learn-english-learna/id6478287397" target="_blank" rel="noopener noreferrer">Learna AI</a><br /><a href="https://apps.apple.com/us/app/lightroom-ai-photo-editor/id878783582" target="_blank" rel="noopener noreferrer">Lightroom</a><br /><a href="https://apps.apple.com/us/app/meitu-photo-video-editor/id416048305" target="_blank" rel="noopener noreferrer">Meitu</a><br /><a href="https://apps.apple.com/us/app/%E7%BE%8E%E5%9B%A2-%E7%BE%8E%E5%A5%BD%E7%94%9F%E6%B4%BB%E5%B0%8F%E5%B8%AE%E6%89%8B/id423084029" target="_blank" rel="noopener noreferrer">Meituan</a><br /><a href="https://apps.apple.com/us/app/meta-ai-vibes-ai-glasses/id1558240027" target="_blank" rel="noopener noreferrer">Meta AI</a><br /><a href="https://apps.apple.com/us/app/microsoft-edge-ai-browser/id1288723196" target="_blank" rel="noopener noreferrer">Microsoft Edge</a><br /><a href="https://apps.apple.com/us/app/microsoft-bing-search/id345323231" target="_blank" rel="noopener noreferrer">Microsoft Bing</a><br /><a href="https://apps.apple.com/us/app/mivi-audio/id6504547307" target="_blank" rel="noopener noreferrer">Mivi</a><br /><a href="https://apps.apple.com/us/app/notion-notes-tasks-ai/id1232780281" target="_blank" rel="noopener noreferrer">Notion</a><br /><a href="https://apps.apple.com/us/app/ai-chatbot-nova/id1669007652" target="_blank" rel="noopener noreferrer">Nova</a><br /><a href="https://apps.apple.com/us/app/naver-papago-ai-translator/id1147874819" target="_blank" rel="noopener noreferrer">Papago</a><br /><a href="https://apps.apple.com/us/app/perplexity-ask-anything/id1668000334" target="_blank" rel="noopener noreferrer">Perplexity</a><br /><a href="https://apps.apple.com/us/app/photomath/id919087726" target="_blank" rel="noopener noreferrer">Photomath</a><br /><a href="https://apps.apple.com/us/app/photoroom-ai-photo-editor/id1455009060" target="_blank" rel="noopener noreferrer">Photoroom</a><br /><a href="https://apps.apple.com/us/app/picsart-ai-photo-editor-video/id587366035" target="_blank" rel="noopener noreferrer">Picsart</a><br /><a href="https://apps.apple.com/us/app/pixverse-ai-video-generator/id6599839203" target="_blank" rel="noopener noreferrer">Pixverse</a><br /><a href="https://play.google.com/store/search?q=ai%20photo%20editor%20polish&amp;c=apps&amp;hl=en_US" target="_blank" rel="noopener noreferrer">Polish</a><br /><a href="https://apps.apple.com/us/app/polybuzz-chat-with-ai-friends/id6449190344" target="_blank" rel="noopener noreferrer">Polybuzz</a><br /><a href="https://apps.apple.com/us/app/qq%E6%B5%8F%E8%A7%88%E5%99%A8-ai%E5%8A%9E%E5%85%AC%E5%AD%A6%E4%B9%A0%E5%8A%A9%E6%89%8B/id370139302" target="_blank" rel="noopener noreferrer">QQ Browser</a><br /><a href="https://apps.apple.com/us/app/remini-ai-photo-enhancer/id1470373330" target="_blank" rel="noopener noreferrer">Remini</a><br /><a href="https://apps.apple.com/us/app/seeke-movies-and-tv-shows/id1596735039" target="_blank" rel="noopener noreferrer">Seekee</a><br /><a href="https://apps.apple.com/us/app/snow-ai-profile/id1022267439" target="_blank" rel="noopener noreferrer">Snow</a><br /><a href="https://apps.apple.com/us/app/vivacut-ai-video-editor/id1489090374" target="_blank" rel="noopener noreferrer">VivaCut</a><br /><a href="https://apps.apple.com/us/app/vn-ai-video-editor/id1343581380" target="_blank" rel="noopener noreferrer">VN</a><br /><a href="https://apps.apple.com/us/app/wink-video-enhancer-editor/id1594288016" target="_blank" rel="noopener noreferrer">Wink</a><br /><a href="https://apps.apple.com/us/app/yandex-browser-with-alice-ai/id483693909" target="_blank" rel="noopener noreferrer">Yandex</a><br /><a href="https://apps.apple.com/us/app/youcut-ai-video-editor/id1620499741" target="_blank" rel="noopener noreferrer">YouCut</a></p></div>]]></description>
      <link>https://a16z.com/100-gen-ai-apps-6/</link>
      <guid>https://a16z.com/100-gen-ai-apps-6/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Welcome to Gas Town. Happy New Year, and Welcome to Gas… | by Steve Yegge | Jan, 2026 | Medium]]></title>
      <description><![CDATA[]]></description>
      <link>https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04</link>
      <guid>https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Site Spy - Website Change Tracker | Monitor Any Webpage]]></title>
      <description><![CDATA[<section class="page-module__meqK-a__hero"><div class="page-module__meqK-a__heroContent"><p>Featured on Chrome Web Store</p><div class="page-module__meqK-a__logoRow"><img alt="Site Spy - Website Change Tracker" width="80" height="80" data-nimg="1" class="page-module__meqK-a__logo c1" src="https://sitespy.app/logo-full.png" /></div><p class="page-module__meqK-a__headline">Track website changes automatically</p><p class="page-module__meqK-a__subheadline">Monitor any webpage for content updates. Get notified the moment something changes. See exactly what was added or removed with visual diffs.</p><div class="page-module__meqK-a__ctaRow"><a class="page-module__meqK-a__ctaBtn page-module__meqK-a__dashboardBtn" href="https://sitespy.app/dashboard">Web Dashboard</a><a href="https://chromewebstore.google.com/detail/site-spy/jeapcpanagdgipcfnncmogeojgfofige" target="_blank" rel="noopener noreferrer" class="page-module__meqK-a__ctaBtn page-module__meqK-a__chromeBtn"><img alt="" width="24" height="24" data-nimg="1" class="c1" src="https://sitespy.app/icons/chrome.svg" />Chrome</a><a href="https://addons.mozilla.org/en-GB/firefox/addon/site-spy/" target="_blank" rel="noopener noreferrer" class="page-module__meqK-a__ctaBtn page-module__meqK-a__firefoxBtn"><img alt="" width="24" height="24" data-nimg="1" class="c1" src="https://sitespy.app/icons/firefox.svg" />Firefox</a></div></div><div class="page-module__meqK-a__heroVisual page-module__meqK-a__screenshotPair"><div class="page-module__meqK-a__mockupContainer"><img alt="Site Spy extension showing list of tracked websites with change indicators" width="317" height="500" data-nimg="1" class="page-module__meqK-a__mockup page-module__meqK-a__darkOnly c1" src="https://sitespy.app/screenshots/popup-watches-dark.png" /><img alt="Site Spy extension showing list of tracked websites with change indicators" width="320" height="508" data-nimg="1" class="page-module__meqK-a__mockup page-module__meqK-a__lightOnly c1" src="https://sitespy.app/screenshots/popup-watches-light.png" />Watch List</div><div class="page-module__meqK-a__mockupContainer"><img alt="Site Spy settings panel with check interval and notification preferences" width="315" height="507" data-nimg="1" class="page-module__meqK-a__mockup page-module__meqK-a__darkOnly c1" src="https://sitespy.app/screenshots/settings-dark.png" /><img alt="Site Spy settings panel with check interval and notification preferences" width="315" height="507" data-nimg="1" class="page-module__meqK-a__mockup page-module__meqK-a__lightOnly c1" src="https://sitespy.app/screenshots/settings-light.png" />Settings</div></div></section><section class="page-module__meqK-a__showcaseSection"><div class="page-module__meqK-a__sectionHeader"><h2>See website changes at a glance</h2><p>Visual diff highlighting shows exactly what content was added, changed, or removed</p></div></section><section class="page-module__meqK-a__extensionSection"><div class="page-module__meqK-a__sectionHeader"><h2>Your monitoring dashboard</h2><p>Manage all your tracked websites from a powerful web dashboard — works on any device</p></div><div class="page-module__meqK-a__dashboardShowcase page-module__meqK-a__browserFrame"><div class="page-module__meqK-a__browserFrameBar"><p>sitespy.app/dashboard</p></div><img alt="Site Spy web dashboard showing tracked websites with status indicators" width="1400" height="810" data-nimg="1" class="page-module__meqK-a__browserFrameImg page-module__meqK-a__darkOnly c1" src="https://sitespy.app/screenshots/dashboard-watches-dark.png" /><img alt="Site Spy web dashboard showing tracked websites with status indicators" width="1400" height="810" data-nimg="1" class="page-module__meqK-a__browserFrameImg page-module__meqK-a__lightOnly c1" src="https://sitespy.app/screenshots/dashboard-watches-light.png" /></div></section><section class="page-module__meqK-a__featuresSection"><div class="page-module__meqK-a__sectionHeader"><h2>Everything you need to monitor website changes</h2><p>Powerful website tracking features, zero configuration</p></div><div class="page-module__meqK-a__featuresGrid"><div class="page-module__meqK-a__featureCard"><h3>One-click website tracking</h3><p>Add any page to your watchlist instantly from your browser toolbar or right-click menu</p></div><div class="page-module__meqK-a__featureCard"><h3>Element inspector</h3><p>Pick specific elements on a page to track instead of monitoring the entire site — perfect for prices, stock status, or headlines</p></div><div class="page-module__meqK-a__featureCard"><h3>Visual diff view</h3><p>Compare live content with previous snapshots — additions in green, removals in red, just like a code diff</p></div><div class="page-module__meqK-a__featureCard"><h3>Snapshot timeline</h3><p>Browse every captured version with timestamps and compare any two snapshots side by side</p></div><div class="page-module__meqK-a__featureCard"><h3>Color-coded tags</h3><p>Organize tracked websites with Finder-style color labels, filter and search instantly</p></div><div class="page-module__meqK-a__featureCard"><h3>Change notifications</h3><p>Browser push notifications, badge counts, email reports, and Telegram messages the moment a tracked page changes</p></div><div class="page-module__meqK-a__featureCard"><h3>Flexible check intervals</h3><p>Set monitoring frequency from every few minutes to weekly — you control when Site Spy checks for updates</p></div><div class="page-module__meqK-a__featureCard"><h3>Cross-device sync</h3><p>Sign in once and access all your tracked websites from any browser or device</p></div></div></section><section class="page-module__meqK-a__mcpSection"><div class="page-module__meqK-a__sectionHeader"><h2>Works with your AI assistant</h2><p>Connect Site Spy to Claude, Cursor, or any MCP-compatible AI agent</p></div><div class="page-module__meqK-a__mcpContent"><div class="page-module__meqK-a__mcpInfo"><h3>What can AI agents do?</h3><ul class="page-module__meqK-a__mcpFeatures"><li>Monitor websites and track changes automatically</li>
<li>Get notified in natural language when content updates</li>
<li>Compare snapshots and summarize what changed</li>
<li>Manage all watches without leaving your AI chat</li>
</ul><a href="https://www.npmjs.com/package/@site-spy/mcp-server" target="_blank" rel="noopener noreferrer" class="page-module__meqK-a__mcpLink">View on npm →</a></div><div class="page-module__meqK-a__mcpCode"><p>claude_desktop_config.json</p><pre class="page-module__meqK-a__mcpCodeBlock">{
  "mcpServers": {
    "site-spy": {
      "command": "npx",
      "args": ["-y", "@site-spy/mcp-server"],
      "env": {
        "SITE_SPY_API_KEY": "your-key"
      }
    }
  }
}</pre></div></div></section><section class="page-module__meqK-a__howSection"><div class="page-module__meqK-a__sectionHeader"><h2>How Site Spy works</h2><p>Start monitoring website changes in under 30 seconds</p></div><div class="page-module__meqK-a__stepsRow"><div class="page-module__meqK-a__stepCard"><p>1</p><h3>Create a free account</h3><p>Sign up at sitespy.app — no credit card needed</p></div><div class="page-module__meqK-a__stepCard"><p>2</p><h3>Add a website</h3><p>Paste any URL or use the browser extension to add pages instantly</p></div><div class="page-module__meqK-a__stepCard"><p>3</p><h3>Get notified</h3><p>Site Spy checks for changes and alerts you when something updates</p></div></div></section><section class="page-module__meqK-a__pricingSection"><div class="page-module__meqK-a__sectionHeader"><h2>Simple, transparent pricing</h2><p>Start free. Upgrade when you need more watches.</p></div><div class="page-module__meqK-a__pricingGrid"><div class="page-module__meqK-a__pricingCard c2"><p>Free</p><p>€0forever</p><ul class="page-module__meqK-a__planFeatures"><li>✓5 watched URLs</li>
<li>✓1 hour minimum recheck</li>
<li>✓5 snapshots per watch</li>
<li>✓30 days snapshot history</li>
<li>✓Full-page &amp; element tracking</li>
<li>✓Visual diff history</li>
<li>✓Browser extension</li>
<li>✓Web dashboard</li>
</ul><a href="https://sitespy.app/login" class="page-module__meqK-a__planCta page-module__meqK-a__planCtaSecondary">Get started free</a></div><div class="page-module__meqK-a__pricingCard page-module__meqK-a__pricingHighlighted c3">Most popular<p>Starter</p><p>€4/ month</p><ul class="page-module__meqK-a__planFeatures"><li>✓25 watched URLs</li>
<li>✓10 min minimum recheck</li>
<li>✓25 snapshots per watch</li>
<li>✓90 days snapshot history</li>
<li>✓Full-page &amp; element tracking</li>
<li>✓Visual diff history</li>
<li>✓Browser extension</li>
<li>✓Web dashboard</li>
<li>✓Email notifications</li>
</ul><a href="https://sitespy.app/dashboard/billing?plan=starter" class="page-module__meqK-a__planCta page-module__meqK-a__planCtaPrimary">Start Starter plan</a></div><div class="page-module__meqK-a__pricingCard c4"><p>Pro</p><p>€8/ month</p><ul class="page-module__meqK-a__planFeatures"><li>✓100 watched URLs</li>
<li>✓1 min minimum recheck</li>
<li>✓100 snapshots per watch</li>
<li>✓1 year snapshot history</li>
<li>✓Full-page &amp; element tracking</li>
<li>✓Visual diff history</li>
<li>✓Browser extension</li>
<li>✓Web dashboard</li>
<li>✓Email notifications</li>
<li>✓Priority support</li>
</ul><a href="https://sitespy.app/dashboard/billing?plan=pro" class="page-module__meqK-a__planCta page-module__meqK-a__planCtaSecondary">Start Pro plan</a></div></div><p class="page-module__meqK-a__pricingNote">Payments processed by <a href="https://lemonsqueezy.com" target="_blank" rel="noopener noreferrer">Lemon Squeezy</a>. Cancel anytime. All prices in EUR.</p></section><section class="page-module__meqK-a__faqSection"><div class="page-module__meqK-a__sectionHeader"><h2>Frequently asked questions</h2><p>Everything you need to know about Site Spy</p></div><div class="page-module__meqK-a__faqGrid"><details class="page-module__meqK-a__faqItem"><summary class="page-module__meqK-a__faqQuestion">What is Site Spy?</summary>                                             
</details><details class="page-module__meqK-a__faqItem"><summary class="page-module__meqK-a__faqQuestion">How does website change detection work?</summary>                                                    
</details><details class="page-module__meqK-a__faqItem"><summary class="page-module__meqK-a__faqQuestion">Is Site Spy free to use?</summary>                                                  
</details><details class="page-module__meqK-a__faqItem"><summary class="page-module__meqK-a__faqQuestion">How can I access Site Spy?</summary>                               
</details><details class="page-module__meqK-a__faqItem"><summary class="page-module__meqK-a__faqQuestion">Can I track specific parts of a page instead of the whole page?</summary>                                     
</details><details class="page-module__meqK-a__faqItem"><summary class="page-module__meqK-a__faqQuestion">Does Site Spy work with AI assistants?</summary>                                  
</details></div></section><section class="page-module__meqK-a__roadmapSection"><div class="page-module__meqK-a__sectionHeader"><h2>Coming soon</h2><p>We're constantly improving Site Spy</p></div><div class="page-module__meqK-a__roadmapGrid"><p>Webhook alerts</p><p>Bulk import</p><p>Mobile companion app</p></div></section><section class="page-module__meqK-a__finalCta"><h2>Ready to track website changes?</h2><p>Join thousands of users who never miss important website updates</p><div class="page-module__meqK-a__ctaRow"><a class="page-module__meqK-a__ctaBtn page-module__meqK-a__dashboardBtn" href="https://sitespy.app/dashboard">Web Dashboard</a><a href="https://chromewebstore.google.com/detail/site-spy/jeapcpanagdgipcfnncmogeojgfofige" target="_blank" rel="noopener noreferrer" class="page-module__meqK-a__ctaBtn page-module__meqK-a__chromeBtn"><img alt="" width="24" height="24" data-nimg="1" class="c1" src="https://sitespy.app/icons/chrome.svg" />Chrome</a><a href="https://addons.mozilla.org/en-GB/firefox/addon/site-spy/" target="_blank" rel="noopener noreferrer" class="page-module__meqK-a__ctaBtn page-module__meqK-a__firefoxBtn"><img alt="" width="24" height="24" data-nimg="1" class="c1" src="https://sitespy.app/icons/firefox.svg" />Firefox</a></div></section>]]></description>
      <link>https://sitespy.app/</link>
      <guid>https://sitespy.app/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[V-bucks are getting more X-pensive | The Verge]]></title>
      <description><![CDATA[<div class="duet--article--lede duet--page-layout--standard-article duet--ledes--standard-lede _1o1f7ku0 _1ymtmqp3">
<div class="_1o1f7ku1 _1o1f7ku2 _1p1nf4x0">
<div class="">
<p class="duet--article--dangerously-set-cms-markup _8enl99h _8enl99g _1xwticta _1xwtict1">﻿Starting on March 19th, Fortnite players will get fewer V-bucks for their money.</p>
</div>
</div>
<div class="_1o1f7ku6">
<div class="_1o1f7ku7">
<div class="_1o1f7ku3 _1o1f7ku9 _13g9mks1 _13g9mks0">
<div class="_13g9mks9">
<time datetime="2026-03-10T14:02:50+00:00">Mar 10, 2026, 2:02 PM UTC</time></div>
</div>
</div>
<div class="_1o1f7ku4 _1ibjt4j0 duet--layout--entry-image _1b9pgly0">
<div class="_1b9pgly1 _1b9pgly2">
<div class="_1ymtmqpn _1ymtmqpx"><img alt="fortnite-blitz-royale" data-chromatic="ignore" data-nimg="fill" class="x271pn0 c5" sizes="(max-width: 768px) 100vw, 700px" srcset="https://platform.theverge.com/wp-content/uploads/sites/2/2026/02/fortnite-blitz-royale.avif" src="https://platform.theverge.com/wp-content/uploads/sites/2/2026/02/fortnite-blitz-royale.avif" /></div>
</div>
<div class="duet--media--caption qama0i0"><cite class="duet--article--dangerously-set-cms-markup _1xwtict2 qama0i5">Image: Epic Games</cite></div>
</div>
</div>
</div><div class="duet--layout--entry-body-container _1t5ltw90 _1ymtmqp3 _1ymtmqp14 _1t5ltw91">
<div class="duet--layout--entry-body _9f4de40">
<div id="zephr-anchor" class="_1ymtmqp11">
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Everything is more expensive now, even <em>Fortnite</em>’s in-game currency. Starting on March 19th, <a href="https://www.fortnite.com/news/fortnite-v-bucks-price-increase">V-bucks packs will include less</a> of the premium currency at the same prices. For instance, players can currently get 1,000 V-bucks for $8.99, but after the price increases they will only get 800 V-bucks at the same rate. The price of <a href="https://www.theverge.com/news/776478/fortnite-v-bucks-need-top-up-item-shop-skins-exact-amount">exact amount packs</a> is increasing from $0.50 per 50 V-bucks to $0.99 per 50 V-bucks.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Epic is also adjusting the price of <em>Fortnite</em>’s Battle Pass, which will now cost 800 V-bucks to access and reward 800 V-bucks upon completion, rather than costing and awarding 1,000 V-bucks as it currently does. Unfortunately, Battle Pass bonus rewards will no longer include V-bucks after next week’s price changes. Epic has also lowered the cost of the OG Pass to 800 V-bucks (previously 1,000) and the LEGO and Music Passes will cost 1,200 V-bucks, rather than 1,400. However, existing V-bucks gift cards can still be redeemed for their printed values.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Epic says “the cost of running Fortnite has gone up a lot,” forcing them to increase their prices. <em>Fortnite</em> isn’t the only Epic game seeing price hikes, either — the premium currency in <em>Fall Guys</em> is <a href="https://www.fallguys.com/en-US/news/price-increases-for-fall-guys-show-bucks-coming-april-8">getting similar pricing changes</a> starting on April 8th.</p>
</div>
</div>
</div>
<div class="duet--layout--rail _1xql9yl0 _1xql9yl1">
<div class="_1xql9yl2 _1xql9yl6 _1xql9yl8">
<form class="a18g6g0 _1ymtmqpz _1ymtmqpj a18g6g5" action="action">
<div class="duet--cta--newsletter a18g6g9">
<div class="a18g6gd">
<h2 class="a18g6gh">The Verge Daily</h2>
<p class="a18g6gi">A free daily digest of the news that matters most.</p>
</div>
<div class="a18g6gy a18g6gz">
<fieldset><div class="a18g6g12 a18g6g11">
<div class="a18g6g16 a18g6g1e duet--cta--form-field-text _1i902bu0"><label for="email" class="_1pbfapu0 _1yjvsxi0">Email (required)</label>
</div>
</div>
</fieldset><div class="a18g6g1q a18g6gj">By submitting your email, you agree to our <a href="https://www.voxmedia.com/legal/terms-of-use" class="a18g6g1p">Terms</a> and <a href="https://www.voxmedia.com/legal/privacy-notice" class="a18g6g1p">Privacy Notice</a>. This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy" class="a18g6g1p">Privacy Policy</a> and <a href="https://policies.google.com/terms" class="a18g6g1p">Terms of Service</a> apply.</div>
</div>
</div>
</form>
</div>
</div>
</div>]]></description>
      <link>https://www.theverge.com/games/892074/fortnite-v-bucks-price-increase-march-2026</link>
      <guid>https://www.theverge.com/games/892074/fortnite-v-bucks-price-increase-march-2026</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[My “grand vision” for Rust | Hacker News]]></title>
      <description><![CDATA[<table border="0" class="comment-tree"><tr class="athing comtr" id="47302821"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=its-kostya" class="hnuser">its-kostya</a> <a href="https://news.ycombinator.com/item?id=47302821">3 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I write production Rust code that becomes critical infra for our customers. I got tired of nil checks in Go and became a squeaky wheel in incident retros, where I finally got the chance to rewrite parts of our system in Rust during a refactor.
<p>I admit the skill issue on my part, but I genuinely struggled to follow the concepts in this article. Working alongside peers who push Rust's bleeding edge, I dread reviewing their code and especially inheriting "legacy" implementations. It's like having a conversation with someone who expresses simple thoughts with ornate vocabulary. Reasoning about code written this way makes me experience profound fatigue and possess an overwhelming desire to return to my domicile; Or simply put, I get tired and want to go home.</p>
<p>Rust's safety guardrails are valuable until the language becomes so complex that reading and reasoning about _business_ logic gets harder, not easier. It reminds me of the kid in "A Christmas Story" bundled so heavily in winter gear he cant put his arms down[0]. At some point, over-engineered safety becomes its own kind of risk even though it is technically safer in some regards. Sometimes you need to just implement a dang state machine and stop throwing complexity at poorly thought-through solutions. End old-man rant.</p>
<p>[0]: <a href="https://youtu.be/PKxsOlzuH0k?si=-88dxtyegTxIvOYI" rel="nofollow">https://youtu.be/PKxsOlzuH0k?si=-88dxtyegTxIvOYI</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305175"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sam0x17" class="hnuser">sam0x17</a> <a href="https://news.ycombinator.com/item?id=47305175">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47309590" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I feel you, but hear me out. OP is right. I've wanted pretty much everything he's talking about here for years, I just never thought of all of this in as quite a formal way as he has. We need the ability to say "this piece of code can't panic". It's super important in the domains I work in. We also need the ability to say "this piece of code can't be non-deterministic". It's also super important in the domains I work in. Having language level support for something like this where I add an extra word to my function def and the compiler guarantees the above would be groundbreaking</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305932"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=awesan" class="hnuser">awesan</a> <a href="https://news.ycombinator.com/item?id=47305932">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305175" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">IMO rust started at this from the wrong direction. Comparing to something like zig which just cannot panic unless the developer wrote the thing that does the panic, cannot allocate unless the developer wrote the allocation, etc.
<p>Rust instead has all these implicit things that just happen, and now needs ways to specify that in particular cases, it doesn't.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308446"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=IshKebab" class="hnuser">IshKebab</a> <a href="https://news.ycombinator.com/item?id=47308446">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305932" class="clicky" aria-hidden="true">parent</a> | <a href="#47309541" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The problem isn't implicit things happening.
<p>He's talking about this problem. Can this code panic?</p>
<pre><code>    foo();
</code></pre>
You can't easily answer that in Rust <em>or</em> Zig. In both cases you have to walk the entire call graph of the function (which could be arbitrarily large) and check for panics. It's not feasible to do by hand. The compiler could do it though.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309801"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaw3y" class="hnuser">throwaw3y</a> <a href="https://news.ycombinator.com/item?id=47309801">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308446" class="clicky" aria-hidden="true">parent</a> | <a href="#47308658" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"Panic-free" labels are so difficult to ascribe without being misleading because temporal memory effects can cause panics. Pusher too much onto your stack because the function happened to be preceded by a ton of other stack allocations? Crash. Heap too full and malloc failed? Crash. These things can happen from user input, so labelling a function no_panic just because it doesn't do any unchecked indexing can dangerously mislead readers into thinking code can't crash when it can.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309960"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47309960">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309801" class="clicky" aria-hidden="true">parent</a> | <a href="#47308658" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's plenty of independent interest in properly bounding stack usage because this would open up new use cases in deep embedded and Rust-on-the-GPU. Basically, if you statically exclude unbounded stack use, you don't even need memory protection to implement guard pages (or similar) for your call stack usage, which Rust now requires. But this probably requires work on the LLVM side, not just on Rust itself.
<p>Failable memory allocations are already needed for Rust-on-Linux, so that also has independent interest.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308658"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=OptionOfT" class="hnuser">OptionOfT</a> <a href="https://news.ycombinator.com/item?id=47308658">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308446" class="clicky" aria-hidden="true">parent</a> | <a href="#47309801" class="clicky" aria-hidden="true">prev</a> | <a href="#47309541" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What about doing something that Java does with the throws keyword? Would that make the checking easier?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309011"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bigfishrunning" class="hnuser">bigfishrunning</a> <a href="https://news.ycombinator.com/item?id=47309011">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308658" class="clicky" aria-hidden="true">parent</a> | <a href="#47321164" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think that's exactly what's being asked for here (via the "panic effect" that the article refers to)
<p>although, I think i'd prefer a "doesn't panic" effect just to keep backwards compatibility (allowing functions to panic by default)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309715"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=3836293648" class="hnuser">3836293648</a> <a href="https://news.ycombinator.com/item?id=47309715">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309011" class="clicky" aria-hidden="true">parent</a> | <a href="#47321164" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Or effect aliases. But given that it's strictly a syntactic transformation it seems like make the wrong default today, fix it in the next edition. (Editions come with tools to update syntax changes)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321164"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mananaysiempre" class="hnuser">mananaysiempre</a> <a href="https://news.ycombinator.com/item?id=47321164">1 day ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308658" class="clicky" aria-hidden="true">parent</a> | <a href="#47309011" class="clicky" aria-hidden="true">prev</a> | <a href="#47309541" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Something like that, except you probably also want to be able to express things like “whatever the callback I’m passed can throw, I can throw all of that and also FooException”. And correctly handle the cases when the callback can throw FooException itself, and when one of the potential exceptions is dependent on a type parameter, and you see how this becomes a whole thing when done properly. But it’s doable.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309541"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=umanwizard" class="hnuser">umanwizard</a> <a href="https://news.ycombinator.com/item?id=47309541">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305932" class="clicky" aria-hidden="true">parent</a> | <a href="#47308446" class="clicky" aria-hidden="true">prev</a> | <a href="#47306343" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Comparing to something like zig which just cannot panic unless the developer wrote the thing that does the panic
<p>The zig compiler can’t possibly guarantee this without knowing which parts of the code were written by you and which by other people (which is impossible).</p>
<p>So really it’s not “the developer” wrote the thing that does the panic, it’s “<em>some</em> developer” wrote it. And how is that different from rust?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306343"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tialaramex" class="hnuser">tialaramex</a> <a href="https://news.ycombinator.com/item?id=47306343">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305932" class="clicky" aria-hidden="true">parent</a> | <a href="#47309541" class="clicky" aria-hidden="true">prev</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Huh? It seems to me that in these respects the two languages are almost identical. If I tell the program to panic, it panics, and if I divide an integer by zero it... panics and either those are both "the developer wrote the thing" or neither is.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306783"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=awesan" class="hnuser">awesan</a> <a href="https://news.ycombinator.com/item?id=47306783">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306343" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In Zig, dividing by 0 does not panic unless you decide that it should or go out of your way to use unsafe primitives [1]. Same for trying to allocate more memory than is available. The general difference is as follows (IMO):
<p>Rust tries to prevent developers from doing bad things, then has to include ways to avoid these checks for cases where it cannot prove that bad things are actually OK. Zig (and many others such as Odin, Jai, etc.) allow anything by default, but surface the fact that issues can occur in its API design. In practice the result is the same, but Rust needs to be much more complex both to do the proving and to allow the developers to ignore its rules.</p>
<p>[1]: <a href="https://ziglang.org/documentation/0.15.2/std/#std.math.divExact" rel="nofollow">https://ziglang.org/documentation/0.15.2/std/#std.math.divEx...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307449"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ivanbakel" class="hnuser">ivanbakel</a> <a href="https://news.ycombinator.com/item?id=47307449">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306783" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Could you clarify what's going on in the Zig docs[0], then? My reading of them is that Zig definitely allows you to try to divide by 0 in a way the compiler doesn't catch, and this results in a panic at runtime.
<p>I'd be interested if this weren't true, since the only feasible compiler solutions to preventing division-by-0 errors are either: defining the behaviour, which always ends up surprising people later on, or; incredibly cumbersome or underperformant type systems/analyses which ensure that denominators are never 0.</p>
<p>It doesn't look like Zig does either of these.</p>
<p>[0]: <a href="https://ziglang.org/documentation/master/#Division-by-Zero" rel="nofollow">https://ziglang.org/documentation/master/#Division-by-Zero</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309885"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomasmg" class="hnuser">thomasmg</a> <a href="https://news.ycombinator.com/item?id=47309885">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47307449" class="clicky" aria-hidden="true">parent</a> | <a href="#47307831" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; the only feasible compiler solutions to preventing division-by-0 errors are either: defining the behaviour, which always ends up surprising people later on, or; incredibly cumbersome or underperformant type systems/analyses which ensure that denominators are never 0.
<p>I don't think it's very cumbersome if the compiler checks if the divisor could be zero. Some programming languages (Kotlin, Swift, Rust, Typescript...) already do something similar for possible null pointer access: they require that you add a check "if s == null" before the access. The same can be done for division (and remainder / modulo). In my own programming language, this is what I do: you can not have a division by zero at runtime, because the compiler does not allow it [1]. In my experience, integer division by a variable is not all that common in reality. (And floating point division does not panic, and integer division by a non-zero constant doesn't panic either). If needed, one could use a static function that returns 0 or panics or whatever is best.</p>
<p>[1] <a href="https://github.com/thomasmueller/bau-lang/blob/main/README.md#division-by-zero" rel="nofollow">https://github.com/thomasmueller/bau-lang/blob/main/README.m...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321665"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ivanbakel" class="hnuser">ivanbakel</a> <a href="https://news.ycombinator.com/item?id=47321665">1 day ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309885" class="clicky" aria-hidden="true">parent</a> | <a href="#47307831" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;Some programming languages (Kotlin, Swift, Rust, Typescript...) already do something similar for possible null pointer access: they require that you add a check "if s == null" before the access.
<p>For Rust, this is not accurate (though I don't know for the other languages). The type system instead simply enforces that pointers are non-null, and no checks are necessary. Such a check appears if the programmer opts in to the nullable pointer type.</p>
<p>The comparison between pointers and integers is not a sensible one, since it's easy to stay in the world of non-null pointers once you start there. There's no equivalent ergonomics for the type of non-zero integers, since you have to forbid many operations that can produce 0 even on non-0 inputs (or onerously check that they never yield 0 at runtime).</p>
<p>&gt;The same can be done for division (and remainder / modulo). In my own programming language, this is what I do: you can not have a division by zero at runtime, because the compiler does not allow it... In my experience, integer division by a variable is not all that common in reality</p>
<p>That's another option, but I hardly find it a real solution, since it involves the programmer inserting a lot of boilerplate to handle a case that might actually never come up in most code, and where a panic would often be totally fine.</p>
<p>Coming back to the actual article, this is where an effect system would be quite useful: programmers who actually want to have their code be panic-free, and who therefore want or need to insert these checks, can mark their code as lacking the panic effect. But I think it's fine for division to be exposed as a panicking operation by default, since it's expected and not so annoying to use.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47332346"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomasmg" class="hnuser">thomasmg</a> <a href="https://news.ycombinator.com/item?id=47332346">23 hours ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47321665" class="clicky" aria-hidden="true">parent</a> | <a href="#47307831" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The syntax in Kotin is: "val name: String? = getName(); if (name != null) { println(name.length) // safe: compiler knows it's not null }" So, there is no explicit type conversion needed.
<p>I'm arguing for integer / and %, there is no need for an explicit "non-zero integer" type: the divisor is just an integer, and the compiler need to have a prove that the value is not zero. For places where panic is fine, there could be a method that explicitly panics in case of zero.</p>
<p>I agree an annotation / effect system would be useful, where you can mark sections of the code "panic-free" or "safe" in some sense. But "safe" has many flavors: array-out-of-bounds, division by zero, stack overflow, out-of-memory, endless loop. Ada SPARK allows to prove absence of runtime errors using "pragma annotate". Also Dafny, Lean have similar features (in Lean you can give a prove).</p>
<p>&gt; I think it's fine for division to be exposed as a panicking operation by default</p>
<p>That might be true. I think division (by non-constants) is not very common, but it would be good to analyze this in more detail, maybe by analyzing a large codebase... Division by zero does cause issues sometimes, and so the question is, how much of a problem is it if you disallow unchecked division, versus the problems if you don't check.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307831"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Turskarama" class="hnuser">Turskarama</a> <a href="https://news.ycombinator.com/item?id=47307831">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47307449" class="clicky" aria-hidden="true">parent</a> | <a href="#47309885" class="clicky" aria-hidden="true">prev</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">More specifically, Zig will return an error type from the division and if this isn't handled THEN it will panic, kind of like an exception except it can be handled with proper pattern matching.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308623"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ben-schaaf" class="hnuser">ben-schaaf</a> <a href="https://news.ycombinator.com/item?id=47308623">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47307831" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I can't find anything related to division returning an error type. Looking at std.math.divExact, rem, mod, add, sub, etc. it looks to me like you're expected to use these if you don't want to panic.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308967"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Turskarama" class="hnuser">Turskarama</a> <a href="https://news.ycombinator.com/item?id=47308967">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308623" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Actually you're right, I was going by the source code which was in the link of the comment you replied to, but I missed that that was specifically for divExact and not just primitive division.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314260"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=MaulingMonkey" class="hnuser">MaulingMonkey</a> <a href="https://news.ycombinator.com/item?id=47314260">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308967" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">(Rust has a similar fn: <a href="https://doc.rust-lang.org/std/primitive.isize.html#method.checked_div" rel="nofollow">https://doc.rust-lang.org/std/primitive.isize.html#method.ch...</a> )</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309208"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=its-kostya" class="hnuser">its-kostya</a> <a href="https://news.ycombinator.com/item?id=47309208">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305175" class="clicky" aria-hidden="true">parent</a> | <a href="#47305932" class="clicky" aria-hidden="true">prev</a> | <a href="#47305801" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I have no argument against using the right tool for a job. Decorating a function with a keyword to have more compile-time guarantees does sound great, but I bet it comes with strings attached that affect how it can be used which will lead to strange business logic. Anecdotally, I have not (perhaps yet) run into a situation where I needed more language features, I felt rust had enough primatives that I could adapt the current feature set to my needs. Yes, at times I had to scrap what I was working on to rewrite it another way so I can have compile-time guarantees. Yes, here language features offer speed in implementing.
<p>Could you share a situation where the behavior is necessary? I am curious if I could work around it with the current feature set.</p>
<p>Perhaps I take issue with peers that throw bleeding edge features in situations that don't warrant them. Last old-man anecdote: as a hobbyist woodworker it pains me to see people buying expensive tools to accomplish something. They almost lack creativity to use their current tools they have. "If I had xyz tool I would build something so magnificent" they say. This amounts to having many, low-quality single-purpose built tools where a single high-quality table saw could fit the need. FYI, a table-saw could suit 90% of your cutting/shaping needs with a right jig. I don't want this to happen in rust.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309511"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47309511">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309208" class="clicky" aria-hidden="true">parent</a> | <a href="#47309551" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Could you share a situation where the behavior is necessary?
<p>The effects mentioned in the article are not too uncommon in embedded systems, particularly if they are subject to more stringent standards (e.g., hard realtime, safety-critical, etc.). In such situations predictability is paramount, and that tends to correspond to proving the absence of the effects in the OP.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310505"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=its-kostya" class="hnuser">its-kostya</a> <a href="https://news.ycombinator.com/item?id=47310505">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309511" class="clicky" aria-hidden="true">parent</a> | <a href="#47309551" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Ah, the embedded application. Very valid point. I'm guilty of forgetting about that discipline.
<p>I do wonder if it is possible to bin certain features to certain, uh, distributions(?), of rust? I'm having trouble articulating what I mean but in essence so users do not get tempted to use all these bells and whistles when they are aimed at a certain domain or application? Or are such language features beneficial for all applications?</p>
<p>For example, sim cards are mini computers that actually implement the JVM and you can write java and run it on sim cards (!). But there is a subset of java that is allowed and not all features are available. In this case it is due to compute/resource restrictions, but something to a similar tune for rust, is that possible?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312073"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47312073">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47310505" class="clicky" aria-hidden="true">parent</a> | <a href="#47309551" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I guess the no_std/alloc/std split is sort of like what you're talking about? It's not an exact match though; I think that split is more borne out of the lack of built-in support some targets have for particular features rather than trying to cordon off subsets of the language to try to prevent users from burning themselves.
<p>On that note, I guess one could hypothetically limit certain effects to certain Rust subsets (for example, an "allocates" effect may require alloc, a "filesystem" effect may require std, etc.), but I'd imagine the general mechanism would need to be usable everywhere considering how foundational some effects can be.</p>
<p>&gt; Or are such language features beneficial for all applications?</p>
<p>To (ab)use a Pixar quote, I suppose one can think of it as "not all applications may need these features, but these features should be usable anywhere".</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309551"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=abeppu" class="hnuser">abeppu</a> <a href="https://news.ycombinator.com/item?id=47309551">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309208" class="clicky" aria-hidden="true">parent</a> | <a href="#47309511" class="clicky" aria-hidden="true">prev</a> | <a href="#47305801" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Could you share a situation where the behavior is necessary? I am curious if I could work around it with the current feature set.
<p>But this kinda isn't about "behavior" of your code; it's about how the compiler (and humans) can confidently reason about your code?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310596"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=its-kostya" class="hnuser">its-kostya</a> <a href="https://news.ycombinator.com/item?id=47310596">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309551" class="clicky" aria-hidden="true">parent</a> | <a href="#47305801" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sorry I don't understand. The result we all want is at compile-time ensuring some behavior cannot happen during runtime. OP argues we need for features built into the language, I am trying to understand what behavior we cannot achieve with the current primatives. So far the only compelling argument is embedded applications have different requirements (that I personally cannot speak to) that separate their use case from, say, deploying to a server for your SaaS company. No doubt there are more, I am trying to discover them.
<p>I am biased to think more features negatively impact how humans can reason about code, leading to more business logic errors. I want to understand, can we make the compiler understand our code differently without additional features, by weidling mastery of the existing primatives? I very well may be wrong in my bias. But human enginuity and creativity is not to be understated. But neither should lazyness. Users will default to "out of box" solutions over building with language primatives. Adding more and more features will dilute our mastery of the fundamentals.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315002"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sam0x17" class="hnuser">sam0x17</a> <a href="https://news.ycombinator.com/item?id=47315002">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47310596" class="clicky" aria-hidden="true">parent</a> | <a href="#47305801" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">For example, in substrate-based blockchains if you panic in runtime code, the chain is effectively bricked, so they use hundreds of clippy lints to try to prevent this from happening, but you can only do so much statically without language level support. There are crates like no_panic however they basically can't be used anywhere there is dynamic memory allocation because that can panic.
<p>Same thing happens in real time trading systems, distributed systems, databases, etc., you have to design some super critical hot path that can never fail, and you want a static guarantee that that is the fact.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305801"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rapnie" class="hnuser">rapnie</a> <a href="https://news.ycombinator.com/item?id=47305801">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305175" class="clicky" aria-hidden="true">parent</a> | <a href="#47309208" class="clicky" aria-hidden="true">prev</a> | <a href="#47305729" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Perhaps there are similarities to Scala, from my anecdotal observation. Coming from Java and doing the Scala coursera course years ago, it feels like arriving in a candy shop. All the wonderful language features are there, true power yours to wield. And then you bump into the code lines crafted by the experts, and they are line for line so 'smart' they take a real long time to figure out how the heck it all fits together.
<p>People say "Rust is more complex to onboard to, but it is worth it", but a lot of the onboarding hurdle is the extra complexity added in by experts being smart. And it may be a reason why a language doesn't get the adoption that the creators hoped for (Scala?). Rust does not have issues with popularity, and the high onboarding barrier, may have positive impact eventually where "Just rewrite it in Rust" is no more, and people only choose Rust where it is most appropriate. Use the right language for the tool.</p>
<p>The complexity of Rust made me check out Gleam [0], a language designed for simplicity, ease of use, and developer experience. A wholly different design philosophy. But not less powerful, as a BEAM language that compiles to Erlang, but also compiles to Javascript if you want to do regular web stuff.</p>
<p>[0] <a href="https://gleam.run" rel="nofollow">https://gleam.run</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306960"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=spockz" class="hnuser">spockz</a> <a href="https://news.ycombinator.com/item?id=47306960">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305801" class="clicky" aria-hidden="true">parent</a> | <a href="#47311260" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">At least from what I’ve seen around me professionally, the issue with most Scala projects was that developers started new projects in Scala while also still learning Scala through a Coursera course, without having a FP background and therefore lacking intuition/experience on which technique to apply when and where. The result was that you could see “more advanced” Scala (as per the course progression) being used in newer code of the projects. Then older code was never refactored resulting in a hodgepodge of different techniques.
<p>This can happen in any language and is more indicative of not having a strong lead safeguarding the consistency of the codebase. Now Scala has had the added handicap of being able to express the same thing in multiple ways, all made possible in later iterations of Scala, and finally homogenised in Scala 3.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311260"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dxxvi" class="hnuser">dxxvi</a> <a href="https://news.ycombinator.com/item?id=47311260">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305801" class="clicky" aria-hidden="true">parent</a> | <a href="#47306960" class="clicky" aria-hidden="true">prev</a> | <a href="#47306134" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree. IMO, Scala can be written in Li Haoyi's way and it's a pleasure to work with. However, the FP and Effect Scala people are too loud and too smart that if I write Scala in Li Haoyi's way, I feel like I'm too stupid. I like Rust because of no GC, no VM and memory safe. If Rust has features that a Joe java programmer like me can't understand, I guess it'll be like Scala.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306134"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ChadNauseam" class="hnuser">ChadNauseam</a> <a href="https://news.ycombinator.com/item?id=47306134">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305801" class="clicky" aria-hidden="true">parent</a> | <a href="#47311260" class="clicky" aria-hidden="true">prev</a> | <a href="#47306812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I honestly just don't believe that Rust is more complex to onboard to compared to languages like Python. It just does not match my experience at all. I've been a professional rust developer for about three years. Every time I look at python code, it's doing something insane where the function argument definition basically looks like line noise with args and kwargs, with no types, so it's impossible to guess what the parameeters will be for any given function. Every python developer I know makes heavy use of the repl just to figure out what methods they can call on some return value of some underdocumented method of a library they're using. The first time I read pandas code, I saw something along the lines of df[df["age"] &lt; 3] and thought I was having a stroke. Yet python has a reputation for being easy to learn and use. We have a python developer on our team and it probably took me about a day to onboard him to rust and get him able to make changes to our (fairly complicated) Rust codebase.
<p>Don't get me wrong, rust has plenty of "weird" features too, for example higher rank trait bounds have a ridiculous syntax and are going to be hard for most people to understand. But, almost no one will ever have to use a higher rank trait bound. I encounter such things much more rarely in rust than in almost any other mainstream language.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306657"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rapnie" class="hnuser">rapnie</a> <a href="https://news.ycombinator.com/item?id=47306657">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306134" class="clicky" aria-hidden="true">parent</a> | <a href="#47309430" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The language itself is not more complex to onboard. For Scala also not. It feels great to have all these language features to ones proposal. The added complexity is in the way how expert code is written. The experts are empowered and productive, but heightens the barrier of entry for newcomers by their practices. Note that they also might expertly write more accessible code to avoid the issue, and then I agree with (though I can't compare to Python, never used it).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309970"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomasmg" class="hnuser">thomasmg</a> <a href="https://news.ycombinator.com/item?id=47309970">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306657" class="clicky" aria-hidden="true">parent</a> | <a href="#47309430" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Hm, you claim that Rust and Scala are not more complex to onboard than Python... but then you say you never used Python? If that's the case, how do you know? Having used both, I do think Rust is harder to onboard, just because there is more syntax that you need to learn. And Rust is a lot more verbose. And that's before you are exposed to the borrow checker.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314975"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rapnie" class="hnuser">rapnie</a> <a href="https://news.ycombinator.com/item?id=47314975">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309970" class="clicky" aria-hidden="true">parent</a> | <a href="#47309430" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I am not mentioning Python at all. I contrasted Rust with Scala.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319867"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomasmg" class="hnuser">thomasmg</a> <a href="https://news.ycombinator.com/item?id=47319867">1 day ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47314975" class="clicky" aria-hidden="true">parent</a> | <a href="#47309430" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well, the parent wrote "I honestly just don't believe that Rust is more complex to onboard to compared to languages like Python." And you wrote "The language itself is not more complex to onboard." So... to contract Rust with Scala, I think it's clearer to write "The language itself is not more complex to onboard _than Scala_."
<p>To that, I completely agree! Scala is one of the most complex languages, similar to C++. In terms of complexity (roughly the number of features) / hardness to onboard, I would have the following list (hardest to easiest): C++, Scala, Rust, Zig, Swift, Nim, Kotlin, JavaScript, Go, Python.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326515"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rapnie" class="hnuser">rapnie</a> <a href="https://news.ycombinator.com/item?id=47326515">1 day ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47319867" class="clicky" aria-hidden="true">parent</a> | <a href="#47309430" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I see the confusion. ChadNauseam mentions Python to another comment of mine, where I mentioned Gleam. In your list hardest-to-easiest perhaps Gleam is even easier than Python. They literally advertise it as "the language you can learn in a day".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47329015"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomasmg" class="hnuser">thomasmg</a> <a href="https://news.ycombinator.com/item?id=47329015">1 day ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47326515" class="clicky" aria-hidden="true">parent</a> | <a href="#47309430" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Thanks a lot! I wasn't aware of Gleam, it really seems simple. I probably wouldn't say "learn in a day", any I'm not sure if it's simpler than Python, but it's statically typed, and this adds some complexity necessarily.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309430"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kibwen" class="hnuser">kibwen</a> <a href="https://news.ycombinator.com/item?id=47309430">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306134" class="clicky" aria-hidden="true">parent</a> | <a href="#47306657" class="clicky" aria-hidden="true">prev</a> | <a href="#47306812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; I honestly just don't believe that Rust is more complex to onboard to compared to languages like Python.</em>
<p>Most people conflate "complexity" and "difficulty". Rust is a less complex language than Python (yes, it's true), but it's also much more difficult, because it requires you to do all the hard work up-front, while giving you enormously more runtime guarantees.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309520"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47309520">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309430" class="clicky" aria-hidden="true">parent</a> | <a href="#47306812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Doing the hard work up front is <em>easier</em> than doing it while debugging a non-trivial system. And there are boilerplate patterns in Rust that allow you to skip the hard work while doing throwaway exploratory programming, just like in "easier" languages. Except that then you can refactor the boilerplate away and end up with a proper high-quality system.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306812"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47306812">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305801" class="clicky" aria-hidden="true">parent</a> | <a href="#47306134" class="clicky" aria-hidden="true">prev</a> | <a href="#47305729" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; And then you bump into the code lines crafted by the experts, and they are line for line so 'smart' they take a real long time to figure out how the heck it all fits together.
<p>Thing is, the alternative to "smart" code that packs a lot into a single line is code where that line turns into multiple pages of code, which is in fact worse for understanding. At least with PL features, you only have to put in the work once and you can grok how they're meant to be used anywhere.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305729"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=chirsz" class="hnuser">chirsz</a> <a href="https://news.ycombinator.com/item?id=47305729">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305175" class="clicky" aria-hidden="true">parent</a> | <a href="#47305801" class="clicky" aria-hidden="true">prev</a> | <a href="#47309590" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can see:
<p>* no-panic: <a href="https://docs.rs/no-panic/latest/no_panic/" rel="nofollow">https://docs.rs/no-panic/latest/no_panic/</a></p>
<p>* Safe Rust has no undefined behavior: <a href="https://news.ycombinator.com/item?id=39564755">https://news.ycombinator.com/item?id=39564755</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313715"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=andriy_koval" class="hnuser">andriy_koval</a> <a href="https://news.ycombinator.com/item?id=47313715">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305729" class="clicky" aria-hidden="true">parent</a> | <a href="#47309590" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">would be great to have no alloc too as op requested.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309590"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=harpiaharpyja" class="hnuser">harpiaharpyja</a> <a href="https://news.ycombinator.com/item?id=47309590">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47305175" class="clicky" aria-hidden="true">prev</a> | <a href="#47309388" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Look, included in the concepts the article discusses are features that people have been wanting for a very long time.
<p>Like, the ability to have multiple mut references to a struct as long as you access disjoint fields? That's amazing!!! A redo of Pin that actually composes with the rest of the language? That's pretty awesome too.</p>
<p>I think you're getting tied up because the the author is describing these features in a very formal way. But someone has to think about these things, especially if they are going to implement them.</p>
<p>Ultimately, these are features that will make Rust's safety features (which really, are Rust's reason for existing) more ergonomic and easier to use. That's the opposite of what you fear.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309388"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kibwen" class="hnuser">kibwen</a> <a href="https://news.ycombinator.com/item?id=47309388">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47309590" class="clicky" aria-hidden="true">prev</a> | <a href="#47304331" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; I genuinely struggled to follow the concepts in this article</em>
<p>I read the HN comments before I read the OP, which made me worry that the post was going to be some hifalutin type wonkiness. But instead the post is basically completely milquetoast, ordinary and accessible. I'm no type theorist--I cannot tell you what a monad is--and I confess that I don't understand how anyone could be intimidated by this article.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310421"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Folcon" class="hnuser">Folcon</a> <a href="https://news.ycombinator.com/item?id=47310421">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309388" class="clicky" aria-hidden="true">parent</a> | <a href="#47304331" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think you're underestimating your competency
<p>Things like effects aren't obvious to people, at least based on my experience of trying to teach it to people</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314144"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wasabi991011" class="hnuser">wasabi991011</a> <a href="https://news.ycombinator.com/item?id=47314144">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47310421" class="clicky" aria-hidden="true">parent</a> | <a href="#47304331" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't agree, the article isn't going deep into effects.
<p>The intro where they describe effects as essentially being "function colors" (referring to another article fairly often linked in hackernews) plus give lots of concrete examples (async, const, try) seems like more than enough to be obvious to the readers.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304331"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nemothekid" class="hnuser">nemothekid</a> <a href="https://news.ycombinator.com/item?id=47304331">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47309388" class="clicky" aria-hidden="true">prev</a> | <a href="#47308121" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I've been on both sides of the fence here - I've bounced between two camps:
<p>1. Go with a better type system. A compiled language, that has sum types, no-nil, and generics.</p>
<p>2. A widely used, production, systems language that implements PL-theory up until the year ~2000. (Effects, as described in this article, was a research topic in 1999).</p>
<p>I started with (1), but as I started to get more and more exposed to (2), you start looking back on times when you fought with the type system and how some of these PL-nerds have a point. I think my first foray into Higher-Kinded Types was trying to rewrite a dynamic python dispatch system into Rust while keeping types at compile time.</p>
<p>The problem is, many of these PL-nerd concepts are rare and kind of hard to grok at first, and I can easily see them scaring people off from the language. However I think once you understand how they work, and the PL-nerds dumb down the language, I think most people will come around to them. Concepts like "sum types" and "monads", are IMO easy to understand concepts with dumb names, and even more complex standard definitions.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305297"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Horusiath" class="hnuser">Horusiath</a> <a href="https://news.ycombinator.com/item?id=47305297">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304331" class="clicky" aria-hidden="true">parent</a> | <a href="#47304712" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; 1. Go with a better type system. A compiled language, that has sum types, no-nil, and generics.
<p>I was looking for something like that and eventually found Crystal (<a href="https://crystal-lang.org" rel="nofollow">https://crystal-lang.org</a>) as a closest match: LLVM compiled, strong static typing with explicit nulls and very good type inference, stackfull coroutines, channels etc.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312239"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kbolino" class="hnuser">kbolino</a> <a href="https://news.ycombinator.com/item?id=47312239">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305297" class="clicky" aria-hidden="true">parent</a> | <a href="#47305785" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Go does not use LLVM at all and never has. It uses its own compiler and its own (quirky) assembler. Of course, this does not matter to most people, but LLVM compilation can be both a blessing (good interop with C/FFI) and a curse (changes to LLVM internals causing issues for languages other than C/C++).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305785"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=brabel" class="hnuser">brabel</a> <a href="https://news.ycombinator.com/item?id=47305785">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305297" class="clicky" aria-hidden="true">parent</a> | <a href="#47312239" class="clicky" aria-hidden="true">prev</a> | <a href="#47304712" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Crystal is a typed Ruby. The closer to Go language would probably be Odin.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305925"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mastermage" class="hnuser">mastermage</a> <a href="https://news.ycombinator.com/item?id=47305925">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305785" class="clicky" aria-hidden="true">parent</a> | <a href="#47306180" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Odin is more of an alternative C than Go. V is inspired by Go has like nearly the same syntax as Go and alot of Goodies. Like Error Types, Sum Types and more.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306180"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pansa2" class="hnuser">pansa2</a> <a href="https://news.ycombinator.com/item?id=47306180">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305785" class="clicky" aria-hidden="true">parent</a> | <a href="#47305925" class="clicky" aria-hidden="true">prev</a> | <a href="#47304712" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Crystal’s syntax is similar to Ruby’s, but AFAIK the similarity more-or-less ends there.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304712"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kelipso" class="hnuser">kelipso</a> <a href="https://news.ycombinator.com/item?id=47304712">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304331" class="clicky" aria-hidden="true">parent</a> | <a href="#47305297" class="clicky" aria-hidden="true">prev</a> | <a href="#47308121" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yeah, (non sarcastically) give those things dumb names like borrow checker and you'll get people swooning over it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308121"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=devnullbrain" class="hnuser">devnullbrain</a> <a href="https://news.ycombinator.com/item?id=47308121">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47304331" class="clicky" aria-hidden="true">prev</a> | <a href="#47306553" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A state machine is a perfect example of a case where you would benefit from linear types.
<p>Some things just need precise terminology so humans can communicate about them to humans without ambiguity. It doesn't mean they're inherently complex: the article provides simple definitions. It's the same for most engineering, science and language. One of the most valuable skills I've learned in my career is to differentiate between expressions, statements, items, etc. - how often have you heard that the hardest problem in software development is coordinating with other developers? If you learn proper terminology, you can say exactly what you mean. Simple language doesn't mean more clear.</p>
<p>I wasn't born knowing Rust, I had to learn it. So I'm always surprised by complaints about Rust being too complex directed at the many unremarkable people who have undergone this process without issues. What does it say, really? That you're not as good as them at learning things? In what other context do software people on the internet so freely share self-doubt?</p>
<p>I also wonder about their career plans for the future. LLMs are already capable of understanding these concepts. The tide is rising.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306553"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ajxs" class="hnuser">ajxs</a> <a href="https://news.ycombinator.com/item?id=47306553">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47308121" class="clicky" aria-hidden="true">prev</a> | <a href="#47307777" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">At the risk of sounding like a language zealot, have you ever looked at Ada? It was explicitly designed to be very readable, and for use in safety-critical systems. Ada isn't perfect in all the ways Rust isn't, and it might not be the right choice for your system, but if you're writing systems software it's worth a look. If you're writing a web backend on the other hand, it's not worth a look at all.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309514"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=9rx" class="hnuser">9rx</a> <a href="https://news.ycombinator.com/item?id=47309514">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306553" class="clicky" aria-hidden="true">parent</a> | <a href="#47307777" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Unless you are going back to CGI, web backends are systems.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307777"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=63stack" class="hnuser">63stack</a> <a href="https://news.ycombinator.com/item?id=47307777">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47306553" class="clicky" aria-hidden="true">prev</a> | <a href="#47311176" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't think this is an old man rant, I think you made a reasonable argument. Rust is certainly at risk of becoming just as complex as c++.
<p>I would love to introduce more rust at work, but I dread that someone is going to ask about for&lt;'a&gt;, use&lt;'a&gt;, differences between impl X vs Box&lt;dyn X&gt;, or Pin/Unpin, and I don't have proper answers either.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314254"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=andriy_koval" class="hnuser">andriy_koval</a> <a href="https://news.ycombinator.com/item?id=47314254">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47307777" class="clicky" aria-hidden="true">parent</a> | <a href="#47311176" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; but I dread that someone is going to ask about for&lt;'a&gt;, use&lt;'a&gt;, differences between impl X vs Box&lt;dyn X&gt;, or Pin/Unpin, and I don't have proper answers either.
<p>its an issue in "someone", all those answers can be received in under 1min from AI.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311176"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=keybored" class="hnuser">keybored</a> <a href="https://news.ycombinator.com/item?id=47311176">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47307777" class="clicky" aria-hidden="true">prev</a> | <a href="#47311366" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust is complex enough as-is. There is definitely a learning curve.
<p>But these top-comments sometimes paint with a broad brush. As in this case.</p>
<p>&gt; I admit the skill issue on my part, but I genuinely struggled to follow the concepts in this article. Working alongside peers who push Rust's bleeding edge, I dread reviewing their code and especially inheriting "legacy" implementations. It's like having a conversation with someone who expresses simple thoughts with ornate vocabulary. Reasoning about code written this way makes me experience profound fatigue and possess an overwhelming desire to return to my domicile; Or simply put, I get tired and want to go home.</p>
<p>Two paragraphs in and nothing concrete yet. We can contrast with the article. Let’s just consider the Effects section.</p>
<p>It describes four examples: <em>functions that</em> 1) don’t unwind, 2) guaranteed termination, 3) are deterministic 4) do not “call host APIs”, which is “IO” somehow? (this last one seems a bit off)</p>
<p>The first point is about not panicking (keyword <em>panic</em> given). Point two is about not looping forever, for example. Point three can be contrasted with non-determinism. Is that jargony? A fancy-pants term for something simpler? The fourth point seems a bit, I don’t know, could be rewritten.</p>
<p>All of these at least attempt to describe concrete things that you get out of an “effects system”.</p>
<p>&gt; Rust's safety guardrails are valuable until the language becomes so complex that reading and reasoning about _business_ logic gets harder, not easier. It reminds me of the kid in "A Christmas Story" bundled so heavily in winter gear he cant put his arms down[0]. At some point, over-engineered safety becomes its own kind of risk even though it is technically safer in some regards. Sometimes you need to just implement a dang state machine and stop throwing complexity at poorly thought-through solutions. End old-man rant.</p>
<p>This is just a parade of the usual adjectives with an unexplained analogy thrown in (how will these additions cripple Rust usage?). “So complex”, “over-engineered safety”, “complexity” (again), “poorly thought-throught solutions”.</p>
<p>TFA is about concrete things. OP here is a bunch of adjectives. And a bunch of words about complexity and not understanding would be fine if TFA did not have any understandable, practical parts. But as we’ve gone over it does...</p>
<p>People see Rust. Then they see a comment reacting to nondescript complexity. The rest is history.</p>
<p>A good anti-complexity comment would address something concrete like Async Rust. And there are plenty of such comments to vote on.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311366"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nine_k" class="hnuser">nine_k</a> <a href="https://news.ycombinator.com/item?id=47311366">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47311176" class="clicky" aria-hidden="true">prev</a> | <a href="#47303704" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">As I was getting into computers as a teenager, a teacher warned me that the area is such that I would have to learn new things constantly, without end. I said, fine, what's not to like?
<p>But I now realize that as people grow, their desire to learn new things sometimes fades, and an illusion of "already knowing enough" may set in.</p>
<p>Don't trust that illusion. We still have to learn new things every day. (And new fancy words for simple concepts is the easy part.)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303704"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=QuaternionsBhop" class="hnuser">QuaternionsBhop</a> <a href="https://news.ycombinator.com/item?id=47303704">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47311366" class="clicky" aria-hidden="true">prev</a> | <a href="#47305433" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Reasoning about code written this way makes me experience profound fatigue and possess an overwhelming desire to return to my domicile;
<p>I didn't understand that you were making fun of verbosity until the word 'domicile'. I must be one of those insufferable people who expresses simple thoughts with ornate vocabulary...</p>
<p>The article was comprehensible to me, and the additional function colorings sound like exciting constraints I can impose to prevent my future self from making mistakes rather than heavy winter gear. I guess I'm closer to the target audience?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305433"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=olalonde" class="hnuser">olalonde</a> <a href="https://news.ycombinator.com/item?id=47305433">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47303704" class="clicky" aria-hidden="true">prev</a> | <a href="#47305477" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Can we get a version of Rust that swaps lifetimes and ownership for a GC and a JS-style event loop? I love the DX of the language, but I don't always need to squeeze out every microsecond of performance at the cost of fighting the borrow checker.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305442"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pharrington" class="hnuser">pharrington</a> <a href="https://news.ycombinator.com/item?id=47305442">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305433" class="clicky" aria-hidden="true">parent</a> | <a href="#47305837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><a href="https://ocaml.org/" rel="nofollow">https://ocaml.org/</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306772"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47306772">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305442" class="clicky" aria-hidden="true">parent</a> | <a href="#47305837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">ReasonML if you want a slightly more Rustic syntax.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305837"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=widdershins" class="hnuser">widdershins</a> <a href="https://news.ycombinator.com/item?id=47305837">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305433" class="clicky" aria-hidden="true">parent</a> | <a href="#47305442" class="clicky" aria-hidden="true">prev</a> | <a href="#47314354" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><a href="https://gleam.run" rel="nofollow">https://gleam.run</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314354"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=andriy_koval" class="hnuser">andriy_koval</a> <a href="https://news.ycombinator.com/item?id=47314354">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305433" class="clicky" aria-hidden="true">parent</a> | <a href="#47305837" class="clicky" aria-hidden="true">prev</a> | <a href="#47309769" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">&gt; I love the DX of the language, but I don't always need to squeeze out every microsecond of performance at the cost of fighting the borrow checker.
<p>you can use smart pointers everywhere and stop be bothered by borrow checker.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309769"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=harpiaharpyja" class="hnuser">harpiaharpyja</a> <a href="https://news.ycombinator.com/item?id=47309769">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305433" class="clicky" aria-hidden="true">parent</a> | <a href="#47314354" class="clicky" aria-hidden="true">prev</a> | <a href="#47308212" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I mean, you're asking for a fundamentally different directing for the language with different tradeoffs? Why are you commenting on an article about Rust? Not everyone wants the same tradeoffs that you do.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308212"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=secondcoming" class="hnuser">secondcoming</a> <a href="https://news.ycombinator.com/item?id=47308212">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47305433" class="clicky" aria-hidden="true">parent</a> | <a href="#47309769" class="clicky" aria-hidden="true">prev</a> | <a href="#47305477" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Then why are you using rust for these tasks?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310869"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=olalonde" class="hnuser">olalonde</a> <a href="https://news.ycombinator.com/item?id=47310869">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47308212" class="clicky" aria-hidden="true">parent</a> | <a href="#47305477" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm not.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305477"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rob74" class="hnuser">rob74</a> <a href="https://news.ycombinator.com/item?id=47305477">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47305433" class="clicky" aria-hidden="true">prev</a> | <a href="#47304093" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I experienced the same kind of fatigue when I read "there are three directions of development which I find particularly interesting: [three things I never heard about nor particularly want to get familiar with]" in the article.
<p>And later, when I read "Because though we’re not doing too bad, we’re no Ada/SPARK yet" I couldn't help thinking that there must be a reason why those languages never became mainstream, and if Rust gets more of these exciting esoteric features, it's probably headed the same way...</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304093"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=baby" class="hnuser">baby</a> <a href="https://news.ycombinator.com/item?id=47304093">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47305477" class="clicky" aria-hidden="true">prev</a> | <a href="#47309527" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I really think that golang makes it easy to read code, rust makes it easy to write code. If Golang had sum types it would be a much nicer language to write complex applications with</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304624"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=haileys" class="hnuser">haileys</a> <a href="https://news.ycombinator.com/item?id=47304624">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304093" class="clicky" aria-hidden="true">parent</a> | <a href="#47309648" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I find Go code mind numbing to read. There's just _so much of it_ that the parts of the code that should jump out at me for requiring greater attention get lost in the noise. Interfaces also make reading Go more difficult than it could be without LSP - there's no `impl Xyz for` to grep for.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307786"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=usrnm" class="hnuser">usrnm</a> <a href="https://news.ycombinator.com/item?id=47307786">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304624" class="clicky" aria-hidden="true">parent</a> | <a href="#47309648" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's the complete opposite for me. Rust code, especially async Rust code is just full of noise the only purpose of which is to make the borrow checker shut up</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309648"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=umanwizard" class="hnuser">umanwizard</a> <a href="https://news.ycombinator.com/item?id=47309648">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304093" class="clicky" aria-hidden="true">parent</a> | <a href="#47304624" class="clicky" aria-hidden="true">prev</a> | <a href="#47309145" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Go makes it easy to read each line of code, not necessarily to understand what the system as a whole is doing.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309145"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=9rx" class="hnuser">9rx</a> <a href="https://news.ycombinator.com/item?id=47309145">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304093" class="clicky" aria-hidden="true">parent</a> | <a href="#47309648" class="clicky" aria-hidden="true">prev</a> | <a href="#47304373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Go does have sum types — but the syntax is awkward and a bit transparent, so many don't recognize it as being there, and those that do don't love using it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309666"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=umanwizard" class="hnuser">umanwizard</a> <a href="https://news.ycombinator.com/item?id=47309666">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309145" class="clicky" aria-hidden="true">parent</a> | <a href="#47304373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Can you enlighten us to what you’re talking about instead of vagueposting like this? What’s the supposed way of simulating sum types in go?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309764"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=9rx" class="hnuser">9rx</a> <a href="https://news.ycombinator.com/item?id=47309764">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309666" class="clicky" aria-hidden="true">parent</a> | <a href="#47304373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I am not sure how would you would simulate them. With enums and structs, I suppose?
<p>However, it also has true sum types:</p>
<pre><code>    type SumType interface { isSumType() }
    type A string
    func (A) isSumType()
    type B int
    func (B) isSumType()
</code></pre>
But as you can see the syntax leaves a lot to be desired and may not be all that obvious to those who are hung up thinking in other languages.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312578"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kbolino" class="hnuser">kbolino</a> <a href="https://news.ycombinator.com/item?id=47312578">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309764" class="clicky" aria-hidden="true">parent</a> | <a href="#47309998" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This forms a closed set of types (A, B, nil -- don't forget nil!) but the compiler doesn't understand it as such and complains that the following type-switch is not exhaustive ("missing return"):
<pre><code>  func Foo(s SumType) bool {
    switch s.(type) {
    case A: return true      
    case B: return true
    case nil: return true
    }
  }
</code></pre>
Also, you, the package author, may know what constitutes SumType, but the consumers of your package don't, at least not without source. Moreover, you can spread A, B, and any other implementations of SumType across many source files, making it hard to answer the question even with source. This is even a problem for the standard library, just consider go/ast and its Decl, Expr, and Stmt interfaces, none of which document what types actually implement them.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312818"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=9rx" class="hnuser">9rx</a> <a href="https://news.ycombinator.com/item?id=47312818">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47312578" class="clicky" aria-hidden="true">parent</a> | <a href="#47309998" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; but the compiler doesn't understand ...</em>
<p>Right — While it does has sum types, it doesn't have some other features found in other languages.</p>
<p>But, of course, if one wanted those features they would talk about those features. In this discussion, we're talking specifically about sum types, which Go most definitely does have.</p>
<p><em>&gt; nil -- don't forget nil!</em></p>
<p>This is why alternative syntax has never been added. Nobody can figure out how to eliminate nil or make it clear that nil is always part of the set in a way that improves upon the current sum types.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309998"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=umanwizard" class="hnuser">umanwizard</a> <a href="https://news.ycombinator.com/item?id=47309998">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309764" class="clicky" aria-hidden="true">parent</a> | <a href="#47312578" class="clicky" aria-hidden="true">prev</a> | <a href="#47304373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">interfaces in go aren’t types, so no, that’s not a sum type, it’s just an interface.
<p>The set of objects that can fulfill that interface is not just string and int, it’s anything in the world that someone might decide to write an isSumType function for.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316610"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kbolino" class="hnuser">kbolino</a> <a href="https://news.ycombinator.com/item?id=47316610">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309998" class="clicky" aria-hidden="true">parent</a> | <a href="#47310097" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Interfaces in Go are structurally typed but they're still types. A variable of an interface type has two components: a pointer to its dynamic type information, including virtual method table, and a pointer to its value. When you consider that any compiled Go program has a finite set of known types concretely implementing each of its interfaces, they essentially become discriminated unions, albeit without Rust's compact inline representation (unless the dynamic type is itself a thin pointer).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310097"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=9rx" class="hnuser">9rx</a> <a href="https://news.ycombinator.com/item?id=47310097">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47309998" class="clicky" aria-hidden="true">parent</a> | <a href="#47316610" class="clicky" aria-hidden="true">prev</a> | <a href="#47304373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; it’s anything in the world that someone might decide to write an isSumType function for.</em>
<p>No. Notice the lowercase tag name. It is impossible for anyone else to add an arbitrary type to the closed set.</p>
<p>Unless your argument is that sum types fundamentally cannot exist? Obviously given a more traditional syntax like,</p>
<pre><code>   type SumType tagged {
      A | B
   }
</code></pre>
...one can come along and add C just the same. I guess that is true in some natural properties of the universe way. It is a poor take in context, however.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304373"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nine_k" class="hnuser">nine_k</a> <a href="https://news.ycombinator.com/item?id=47304373">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47304093" class="clicky" aria-hidden="true">parent</a> | <a href="#47309145" class="clicky" aria-hidden="true">prev</a> | <a href="#47309527" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Golang makes easy-to-skim code, with all the `if err != nil` after every function call.
<p>Rust requires actual reading, like Typescript, only more detailed.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309527"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dilawar" class="hnuser">dilawar</a> <a href="https://news.ycombinator.com/item?id=47309527">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47304093" class="clicky" aria-hidden="true">prev</a> | <a href="#47306221" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">&gt; I got tired of nil checks in Go and became a squeaky wheel in incident retros, where I finally got the chance to rewrite parts of our system in Rust during a refactor.
<p>At a new job, I am writing my first microservice in golang. Used to be a Rust/C++ (kernel) and Python/PHP/JS dev (fullstack). Rust is allowed by team is heavily invested in go already.. I don't think I'll be able to convince them to learn rust! Lol</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306221"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gignico" class="hnuser">gignico</a> <a href="https://news.ycombinator.com/item?id=47306221">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47309527" class="clicky" aria-hidden="true">prev</a> | <a href="#47306930" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think the misunderstanding here is that the article was not intended to users but to other language designers.
<p>As a user, using a feature such as pattern types will be natural if you know the rest of the language.</p>
<p>Do you have a function that accepts an enum `MyEnum` but has an `unreachable!()` for some variant that you know is impossible to have at that point?</p>
<p>Then you can accept a `MyEnum is MyEnum::Variant | MyEnum::OtherVariant` instead of `MyEnum` to tell which are the accepted variants, and the pattern match will not require that `unreachable!()` anymore.</p>
<p>The fact someone does not know this is called "refinement types" does not limit their ability to use the feature effectively.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310036"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomasmg" class="hnuser">thomasmg</a> <a href="https://news.ycombinator.com/item?id=47310036">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47306221" class="clicky" aria-hidden="true">parent</a> | <a href="#47306930" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; the article was not intended to users but to other language designers.
<p>That might be true, but it shows the direction that Rust is talking: put in the kitchen sink, just like C++ and Scala did. And _that_ is very much important for users.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310839"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gignico" class="hnuser">gignico</a> <a href="https://news.ycombinator.com/item?id=47310839">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47310036" class="clicky" aria-hidden="true">parent</a> | <a href="#47306930" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm not sure it shows that. Even basic features of Rust we take from granted come from concepts common users do not need to understand. Borrowing of lifetime draws from affine types, but nobody cares when writing Rust code. If in 2012 you read a similar article explaining borrow checking in academic terms you would have thought Rust would be unusably hard, which is not.
<p>Also I do not think that adding features is always bad to the point of comparing with Scala. Most of the things the article mentions will be almost invisible to users. For example, the `!Forget` thing it mentions will just end up with users getting new errors for things that before would have caused memory leaks. What a disgrace!</p>
<p>Then, pattern types allow you to remove panics from code, which is super helpful in many critical contexts where Rust is used in production, even in the Linux kernel once they will bump the language version so far.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311045"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47311045">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47310839" class="clicky" aria-hidden="true">parent</a> | <a href="#47306930" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; If in 2012 you read a similar article explaining borrow checking in academic terms you would have thought Rust would be unusably hard, which is not.
<p>Ironically, Rust was unusably hard prior to the late-2018 edition. So now your academic article has to explain both the baseline borrow checker and non-lexical lifetimes, a vast increase in complexity.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311445"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gignico" class="hnuser">gignico</a> <a href="https://news.ycombinator.com/item?id=47311445">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">root</a> | <a href="#47311045" class="clicky" aria-hidden="true">parent</a> | <a href="#47306930" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Your statement contradicts itself. It was unusable hard before non-lexical lifetimes, but they vastly increased the complexity? Then maybe what’s complex for <em>compiler writers</em> to implement can make the user’s life easier by lowering the complexity of <em>their</em> code?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306930"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tormeh" class="hnuser">tormeh</a> <a href="https://news.ycombinator.com/item?id=47306930">2 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">parent</a> | <a href="#47306221" class="clicky" aria-hidden="true">prev</a> | <a href="#47304273" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">Nothing can really save you from architecture astronauts, except possibly Go, but I hear there are people templating Go with preprocessors, so who knows. This is a human problem. On the other hand I hear you. The moment Rust gets proper async traits an entire world of hexagonal pain will open up for the victims of the astronauts. So it will get even worse, basically. I think if we could solve the problem of bored smart people sabotaging projects it'd be amazing.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304273"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pornel" class="hnuser">pornel</a> <a href="https://news.ycombinator.com/item?id=47304273">3 days ago</a> | <a href="#47302821" class="clicky" aria-hidden="true">prev</a> | <a href="#47304832" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's hard to see features through the programming language theory jargon, but solid theoretical foundations have worked well for Rust so far.
<p>Jargon terms like "sum types" or "affine types" may seem complicated, but when you see it's actually "enums with data fields", it makes so much sense, and prevents plenty of state-related bugs.</p>
<p>Proposed "effects" mean that when you're writing an iterator or a stream, and need to handle error or await somewhere in the chain, you won't suddenly have a puzzle how to replace all of the functions in the entire chain and your call stack with their async or fallible equivalents.</p>
<p>"linear types" means that Rust will be able to have more control over destruction and lifetime of objects beyond sync call stack, so the tokio::spawn() (the "Rust async sucks" function) won't have to be complaining endlessly about lifetimes whenever you use a local variable.</p>
<p>I can't vouch for the specifics of the proposed features (they have tricky to design details), but it's not simply Rust getting more complex, but rather Rust trying to solve and <em>simplify</em> more problems, with robust and generalizable language features, rather than ad-hoc special cases. When it works it makes the language more uniform overall and gives a lot of bang for the buck in terms of complexity vs problems solved.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305448"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47305448">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">parent</a> | <a href="#47304832" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c88">What worked for rust is having enums, sane-ish error handling, having sane integer types and the borrow checker, good tooling. The rest is just not that useful compared to how much garbage it creates</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306063"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ChadNauseam" class="hnuser">ChadNauseam</a> <a href="https://news.ycombinator.com/item?id=47306063">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47305448" class="clicky" aria-hidden="true">parent</a> | <a href="#47304832" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You didn't mention parametric polymorphism, which is incredibly useful and important to the language. I'm guessing you intentionally excluded async, but to describe it as "not that useful" would just be wrong, there is a large class of programs that can be expressed very simply using async rust but would be very complicated to express in sync rust (assuming equivalent performance).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306291"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47306291">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306063" class="clicky" aria-hidden="true">parent</a> | <a href="#47306388" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes rust async isn’t good imo. You can do basically the same thing with stackfull coroutines.
<p>Also the ecosystem is setup so you have to use tokio and everything has to be an Arc.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310897"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47310897">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306291" class="clicky" aria-hidden="true">parent</a> | <a href="#47311107" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, stackful coroutines requires a runtime. Not going to work on embedded, which is where async rust shines the strongest.
<p>If you don't care about embedded that is fine. But almost all systems in the world are embedded. "Normal" computers are the odd ones out. Every "normal" computer has several embedded systems in it (one or more of SSD controller, NIC, WiFi controller, celular modem, embedded controller, etc). And then cars, appliances, cameras, routers, toys, etc have many more.</p>
<p>It is a use case that matters. To have secure and reliable embedded systems is important to humanity's future. We need to turn the trend of major security vulnerabilities and buggy software in general around. Rust is part of that story.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311107"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jandrewrogers" class="hnuser">jandrewrogers</a> <a href="https://news.ycombinator.com/item?id=47311107">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306291" class="clicky" aria-hidden="true">parent</a> | <a href="#47310897" class="clicky" aria-hidden="true">prev</a> | <a href="#47309557" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A stackfull coroutine is brittle and doesn't compose as cleanly as stackless coroutines. As a default language primitive, the latter is almost always the robust choice. Most devs should be using stackless coroutines for async unless they can articulate a technical justification for introducing the issues that stackfull coroutines bring with them.
<p>I've implemented several stackfull and stackless async engines from scratch. When I started out I had a naive bias toward stackfull but over time have come to appreciate that stackless is the correct model even if it seems more complicated to use.</p>
<p>That said, I don't know why everyone uses runtimes like tokio for async. If performance is your objective then not designing and writing your own scheduler misses the point.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309557"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kibwen" class="hnuser">kibwen</a> <a href="https://news.ycombinator.com/item?id=47309557">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306291" class="clicky" aria-hidden="true">parent</a> | <a href="#47311107" class="clicky" aria-hidden="true">prev</a> | <a href="#47306490" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; You can do basically the same thing with stackfull coroutines.</em>
<p>It's clear that you don't understand the use cases that async in Rust was designed to accommodate.</p>
<p><em>&gt; Also the ecosystem is setup so you have to use tokio and everything has to be an Arc.</em></p>
<p>It's clear that you're not at all familiar with the Rust async ecosystem, including Embassy.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310598"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47310598">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47309557" class="clicky" aria-hidden="true">parent</a> | <a href="#47306490" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I understand what that is but I just don’t care. I am guessing the vast majority of people using rust also don’t care. Justifying the decision to create this mess by saying it is for embedded makes no sense to me.
<p>Also don’t understand why you would use rust for embedded instead of c</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310931"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47310931">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47310598" class="clicky" aria-hidden="true">parent</a> | <a href="#47306490" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Embedded systems vastly outnumber classical computers. Every classical computer has several embedded systems in them. As does appliances, cars, etc. So yes they are an incredible important use case to secure our modern infrastructure.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306490"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47306490">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306291" class="clicky" aria-hidden="true">parent</a> | <a href="#47309557" class="clicky" aria-hidden="true">prev</a> | <a href="#47306388" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; You can do basically the same thing with stackfull coroutines.
<p>...Minus the various tradeoffs that made stackful coroutines a nonstarter for Rust's priorities. For example, Rust wanted:</p>
<p>- Tight control over memory use (no required heap allocation, so segmented stacks are out)</p>
<p>- No runtime (so no stack copying and/or pointer rewriting)</p>
<p>- Transparent/zero-cost interop over C FFI (i.e., no need to copy a coroutine stack to something C-compatible when calling out to FFI)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307098"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47307098">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306490" class="clicky" aria-hidden="true">parent</a> | <a href="#47306388" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"Tight control over memory use" sounds wrong considering every single allocation in rust is done through the global allocator. And pretty much everything in rust async is put into an Arc.
<p>I don't understand what kind of use case they were optimizing for when they designed this system. Don't think they were optimizing only for embedded or similar applications where they don't use a runtime at all.</p>
<p>Using stackfull coroutines, having a trait in std for runtimes and passing that trait around into async functions would be much better in my opinion instead of having the compiler transform entire functions and having more and more and more complexity layered on top of it solve the complexities that this decision created.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308402"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47308402">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47307098" class="clicky" aria-hidden="true">parent</a> | <a href="#47308315" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; "Tight control over memory use" sounds wrong considering every single allocation in rust is done through the global allocator.
<p>In the case of Rust's async design, the answer is that that simply isn't a problem when your design was intentionally chosen to not require allocation in the first place.</p>
<p>&gt; And pretty much everything in rust async is put into an Arc.</p>
<p>IIRC that's more a tokio thing than a Rust async thing in general. Parts of the ecosystem that use a different runtime (e.g., IIRC embassy in embedded) don't face the same requirements.</p>
<p>I think it would be nice if there were less reliance on specific executors in general, though.</p>
<p>&gt; Don't think they were optimizing only for embedded or similar applications where they don't use a runtime at all.</p>
<p>I would say less that the Rust devs were optimizing for such a use case and more that they didn't want to preclude such a use case.</p>
<p>&gt; having a trait in std for runtimes and passing that trait around into async functions</p>
<p>Yes, the lack of some way to abstract over/otherwise avoid locking oneself into specific runtimes is a known pain point that seems to be progressing at a frustratingly slow rate.</p>
<p>I could have sworn that that was supposed to be one of the improvements to be worked on after the initial MVP landed in the 2018 edition, but I can't seem to find a supporting blog post so I'm not sure I'm getting this confused with the myriad other sharp edges Rust's sync design has.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314983"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=12_throw_away" class="hnuser">12_throw_away</a> <a href="https://news.ycombinator.com/item?id=47314983">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47308402" class="clicky" aria-hidden="true">parent</a> | <a href="#47308315" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; &gt; And pretty much everything in rust async is put into an Arc.
<p>&gt; IIRC that's more a tokio thing than a Rust async thing in general. Parts of the ecosystem that use a different runtime (e.g., IIRC embassy in embedded) don't face the same requirements.</p>
<p>Well, if you're implementing an async rust executor, the current async system gives you exactly 2 choices:</p>
<p>1) Implement the `Wake` trait, which <em>requires</em> `Arc` [1], or</p>
<p>2) Create your own `RawWaker` and `RawWakerVTable` instances, which are gobsmackingly unsafe, including `void*` pointers and DIY vtables [2]</p>
<p>[1] <a href="https://doc.rust-lang.org/std/task/trait.Wake.html" rel="nofollow">https://doc.rust-lang.org/std/task/trait.Wake.html</a></p>
<p>[2] <a href="https://doc.rust-lang.org/std/task/struct.RawWaker.html" rel="nofollow">https://doc.rust-lang.org/std/task/struct.RawWaker.html</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319020"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47319020">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47314983" class="clicky" aria-hidden="true">parent</a> | <a href="#47308315" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sure, but those are arguably more like implementation details as far as end users are concerned, aren't they? At least off the top of my head I'd imagine tokio would require Send + Sync for tasks due to its work-stealing architecture regardless of whether it uses Wake or RawWaker/RawWakerVTable internally.
<p>I find it interesting that there's relatively recent discussion about adding LocalWaker back in [0] after it was removed [1]. Wonder what changed.</p>
<p>[0]: <a href="https://github.com/rust-lang/libs-team/issues/191" rel="nofollow">https://github.com/rust-lang/libs-team/issues/191</a></p>
<p>[1]: <a href="https://github.com/aturon/rfcs/pull/16" rel="nofollow">https://github.com/aturon/rfcs/pull/16</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308315"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lionkor" class="hnuser">lionkor</a> <a href="https://news.ycombinator.com/item?id=47308315">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47307098" class="clicky" aria-hidden="true">parent</a> | <a href="#47308402" class="clicky" aria-hidden="true">prev</a> | <a href="#47306388" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can do rust async by moving instead of sharing data, for example</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306388"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47306388">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306063" class="clicky" aria-hidden="true">parent</a> | <a href="#47306291" class="clicky" aria-hidden="true">prev</a> | <a href="#47304832" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Generics are incredibly overused in rust like most other features. I’m pretty sure most programs don’t need generics outside of use cases like HashMap</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310388"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=DangitBobby" class="hnuser">DangitBobby</a> <a href="https://news.ycombinator.com/item?id=47310388">2 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">root</a> | <a href="#47306388" class="clicky" aria-hidden="true">parent</a> | <a href="#47304832" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Lack of generics generally makes a modern language DoA unless some company dumps ungodly amounts of money into it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304832"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simplesocieties" class="hnuser">simplesocieties</a> <a href="https://news.ycombinator.com/item?id=47304832">3 days ago</a> | <a href="#47304273" class="clicky" aria-hidden="true">prev</a> | <a href="#47295232" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The rust maintainers need to learn from the mistakes of the c++ design committee and understand that not adding a feature at all is in itself a desirable feature.
<p>For example, your section on effects:</p>
<p>&gt; Functions which guarantee they do not unwind (absence of the panic effect)</p>
<p>* I actually don’t see how this is any more beneficial than the existing no_panic macro <a href="https://docs.rs/no-panic/latest/no_panic/" rel="nofollow">https://docs.rs/no-panic/latest/no_panic/</a></p>
<p>&gt; Functions which guarantee they terminate (absence of the div effect)</p>
<p>&gt; Functions which are guaranteed to be deterministic (absence of the ndet effect)</p>
<p>&gt; Functions which are guaranteed to not call host APIs (absence of the io effect)</p>
<p>The vast majority of rust programs don’t need such validation. And for those that do, the Ferrocene project is maintaining a downstream fork of the compiler where this kind of feature would be more appropriate.</p>
<p>I think rust is in a perfect spot right now. Covers 99.99% of use cases and adding more syntax/functionality for 0.001% of users is only going to make the language worse. The compiler itself provides a powerful api via build.rs and proc macros which let downstream maintainers build their desired customization.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309615"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kibwen" class="hnuser">kibwen</a> <a href="https://news.ycombinator.com/item?id=47309615">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">parent</a> | <a href="#47308287" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; The vast majority of rust programs don’t need such validation.</em>
<p>The vast majority of Rust programs would benefit from such validation existing in the language, even if they never bother to explicitly leverage it themselves. For example, a non-panicking effect would be beneficial for both compilation times (don't bother pessimistically emitting unwinding glue for the enormous number of functions that don't need it, only to attempt to optimize it away later) and runtime performance (the guaranteed absence of the aforementioned glue reduces potential branch points and code size, which leads to better inlining and vectorization).</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308287"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=krautsauer" class="hnuser">krautsauer</a> <a href="https://news.ycombinator.com/item?id=47308287">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">parent</a> | <a href="#47309615" class="clicky" aria-hidden="true">prev</a> | <a href="#47305778" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The "caveats" section in its docs hints at it, but to be explicit: no_panic is a band-aid that can break when changing optimizer options or compiler/llvm version. It's not a good option for library crates, e.g.
<p>That being said, I'm not at all happy with all the complexity and ecosystem fragmentation that async brought. I understand what you're saying. But surprise panics is a bit of a pain point for me.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311201"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dtolnay" class="hnuser">dtolnay</a> <a href="https://news.ycombinator.com/item?id=47311201">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">root</a> | <a href="#47308287" class="clicky" aria-hidden="true">parent</a> | <a href="#47305778" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; It's not a good option for library crates, e.g.</em>
<p>Author here. Yes, it is. It was literally made for libraries. Notably <a href="https://github.com/dtolnay/zmij" rel="nofollow">https://github.com/dtolnay/zmij</a> and <a href="https://github.com/dtolnay/itoa" rel="nofollow">https://github.com/dtolnay/itoa</a> use it to enforce that the libraries' public API is absent of panicking.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305778"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=chiffaa" class="hnuser">chiffaa</a> <a href="https://news.ycombinator.com/item?id=47305778">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">parent</a> | <a href="#47308287" class="clicky" aria-hidden="true">prev</a> | <a href="#47305417" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There are ways to handle these effects without bloating up normal applications. For example, using attributes implemented as intrinsics, which wouldn't really affect anything that isn't using them.
<p>The thing is, some of these things are very useful in specific domains, and all these domains are closely related to the ideas of safety. Nondeterminism and IO are important for purity/referential transparency, which is a fairly important effect for business logic IMO. Guaranteed termination matters for formal verification. Unwind removal matters for embedded. I don't think wishing for these things is really all that unwarranted</p>
<p>&gt; I actually don’t see how this is any more beneficial than the existing no_panic macro</p>
<p>no_panic and similar macros are doing a very hacky workaround which isn't really a great static guarantee. The simple fact that building with panic = abort makes the macro useless is an annoyance in and of itself. dtolnay did great when figuring out <em>some</em> path forward but it's somewhat shaky</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311503"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dtolnay" class="hnuser">dtolnay</a> <a href="https://news.ycombinator.com/item?id=47311503">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">root</a> | <a href="#47305778" class="clicky" aria-hidden="true">parent</a> | <a href="#47305417" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If a piece of code does not panic in panic=unwind, then it does not panic in panic=abort either. So having coverage of panic=unwind would be sufficient to guarantee that code cannot panic. The caveat you mention with panic=abort would only apply to code that is unable to build for panic=unwind, which is uncommon.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312115"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=chiffaa" class="hnuser">chiffaa</a> <a href="https://news.ycombinator.com/item?id=47312115">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">root</a> | <a href="#47311503" class="clicky" aria-hidden="true">parent</a> | <a href="#47305417" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oh, then I misremembered and misunderstood the note, my apologies
<p>On that note, thank you for all your work!</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305417"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47305417">3 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">parent</a> | <a href="#47305778" class="clicky" aria-hidden="true">prev</a> | <a href="#47306368" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">You just know some guy will try to make cli code no-panic/deterministic use a bunch of crap and think he achieved something.
<p>Just not allowing complex code is so much better than this.</p>
<p>Just even being able to look at a piece of code and trace what it is doing is 1000x more valuable than this. I regretted almost every time I allowed Traits/generics into a codebase</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306368"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47306368">2 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">parent</a> | <a href="#47305417" class="clicky" aria-hidden="true">prev</a> | <a href="#47295232" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">&gt; I actually don’t see how this is any more beneficial than the existing no_panic macro
<p>I think looking at the caveats listed in the no_panic docs should give you some ideas as to how a "proper" no_panic effect could improve on the macro.</p>
<p>Furthermore, a "proper" effect system should make working with effects nicer <em>in general</em> - for instance, right now writing functions that work independently of effects is not particularly ergonomic.</p>
<p>&gt; The vast majority of rust programs don’t need such validation.</p>
<p>I think you also need to consider the niches which Rust wants to target. Rust is intended to be usable for very low-level/foundational/etc. niches where being able to track such effects is handy, if not outright required, so adding such support would be unblocking Rust for use in places the devs want it to be usable in.</p>
<p>&gt; And for those that do, the Ferrocene project is maintaining a downstream fork of the compiler where this kind of feature would be more appropriate.</p>
<p>Given this bit from the Ferrocene website:</p>
<p>&gt; Ferrocene is downstream from Rust</p>
<p>&gt; It works with existing Rust infrastructure and the only changes made in the code were to cover testing requirements of ISO 26262, IEC 61508 and IEC 62304 qualification. All fixes are reported upstream for constant improvement.</p>
<p>I would suspect that such changes would be out of scope for the Ferrocene fork because that fork is more intended to be a qualified/certified Rust more than Rust + completely novel extensions.</p>
<p>&gt; The compiler itself provides a powerful api via build.rs and proc macros which let downstream maintainers build their desired customization.</p>
<p>Given the complexity of the features listed this feels tantamount to asking each individual consumer to make their own fork which doesn't seem very likely to attract much interest. IIRC async even started off like that (i.e., using a macro), but that was painful enough and async thought to be useful enough to be promoted to a language feature.</p>
<p>I'm curious to what extent one can implement the described features using just build.rs/proc macros in the first place without effectively writing a new compiler.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295232"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Animats" class="hnuser">Animats</a> <a href="https://news.ycombinator.com/item?id=47295232">3 days ago</a> | <a href="#47304832" class="clicky" aria-hidden="true">prev</a> | <a href="#47259148" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This may be too much advanced type theory for a useful language.
<p>You can go all the way to formal verification. This is not enough for that. Or you can stop at the point all memory error holes have been plugged. That's more useful.</p>
<p>You can go way overboard with templates/macros/traits/generics. Remember C++ and Boost. I understand that Boost is now deprecated.</p>
<p>I should work some more on my solution to the back-reference problem in Rust. The general idea is that Rc/Weak/upgrade/downgrade provide enough expressive power for back references, but the ergonomics are awful. That could be fixed, and some of the checking moved to compile time for the single owner/multiple users case.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295728"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway27448" class="hnuser">throwaway27448</a> <a href="https://news.ycombinator.com/item?id=47295728">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47295373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; You can go way overboard with templates/macros/traits/generics.
<p>You can go overboard on any language concept imaginable, but conflating all these mechanisms makes it sound like you haven't interacted much with non-C++ languages—particularly since rust doesn't have templates or anything like templates, traits are an entirely unrelated composition mechanism, and macros are entirely unrelated to the type discussion in the article.</p>
<p>This isn't really "advanced type theory" so much as picking up programming language developments from the 90s. I suppose it's "advanced" in the sense that it's a proper type system and not a glorified macro ala templating, but how is that a bad thing?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301010"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Cpoll" class="hnuser">Cpoll</a> <a href="https://news.ycombinator.com/item?id=47301010">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47295728" class="clicky" aria-hidden="true">parent</a> | <a href="#47295373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Agreed. Generics are in most modern typed languages, and traits are essentially interfaces. Maybe templates means C++ templates, which are essentially generics?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301658"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nesarkvechnep" class="hnuser">nesarkvechnep</a> <a href="https://news.ycombinator.com/item?id=47301658">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301010" class="clicky" aria-hidden="true">parent</a> | <a href="#47301465" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In C++, concepts are essentially generics where templates are more like weird macros.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301465"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mihaelm" class="hnuser">mihaelm</a> <a href="https://news.ycombinator.com/item?id=47301465">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301010" class="clicky" aria-hidden="true">parent</a> | <a href="#47301658" class="clicky" aria-hidden="true">prev</a> | <a href="#47295373" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">My guess is they meant metaprogramming in general (templates/generics, macros), but traits are not quite like the others.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295373"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wofo" class="hnuser">wofo</a> <a href="https://news.ycombinator.com/item?id=47295373">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47295728" class="clicky" aria-hidden="true">prev</a> | <a href="#47302779" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Thanks for posting this! As a long-time Rust user (and contributor, in the good old days), the thing that has always fascinated me about Rust is the healthy balance it strikes between academic brilliance and industry pragmatism. Radical changes like the ones suggested by the OP risk damaging that balance IMO. I'd rather put up with some language quirks and see Rust achieve "boring technology" status...
<p>But who knows, maybe the "academic brilliance" from the article is more pragmatic than I give it credit for. I sure hope for it if these changes ever go through.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301095"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Animats" class="hnuser">Animats</a> <a href="https://news.ycombinator.com/item?id=47301095">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47295373" class="clicky" aria-hidden="true">parent</a> | <a href="#47301024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The lack of use cases in that document is a concern. They're all "nice to have" features, but is the payoff there for real work? The "effects" section mentions properties useful for a proof system. But it's not part of a proof system. If it were, most of those could be found automatically by static analysis, without bothering the programmer. (I was doing that decades ago in a very early proof of correctness system.) Getting programmers to annotate items is tough. Just getting C++ programmers to use "const" enough is hard.
<p>"View types" are interesting. But how much of that generality is really needed? We already have it for arrays, with "split_at_mut" and its friends. That's a library function which uses "unsafe" but exports a safe interface. The compiler will already let you pass two different fields of a struct as "&amp;mut". That covers the two most pressing cases.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301958"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonask" class="hnuser">simonask</a> <a href="https://news.ycombinator.com/item?id=47301958">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301095" class="clicky" aria-hidden="true">parent</a> | <a href="#47304264" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I would also have liked to see some motivational examples, but I think the most interesting upside of an effect system is composability.
<p>Rust is actually really unique among imperative languages in its general composability - things just compose really well across most language features.</p>
<p>The big missing pieces for composability are higher-kinded types (where you could be generic over Option, Result, etc.), and effects (where you could be generic over async-fn, const-fn, hypothetical nopanic-fn, etc.)</p>
<p>The former becomes obvious with the amount of interface duplication between types like Option and Result. The latter becomes obvious with the number of variants of certain functions that essentially do the same thing but with a different color.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302610"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47302610">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301958" class="clicky" aria-hidden="true">parent</a> | <a href="#47306867" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Some uses of higher-kinded types (though not all of them) can be addressed by leveraging Generic Associated Types (GAT).
<p>Part of the problems is that the "things just compose really well" point becomes gradually less and less applicable as you involve the lower-level features Rust must be concerned with. Abstractions start to become very leaky and it's not clear how best to patch things up without a large increase in complexity. A lot of foundational PL research is needed to address this sensibly.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306867"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306867">2 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301958" class="clicky" aria-hidden="true">parent</a> | <a href="#47302610" class="clicky" aria-hidden="true">prev</a> | <a href="#47309112" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not so much composability on async Rust.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309112"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gf000" class="hnuser">gf000</a> <a href="https://news.ycombinator.com/item?id=47309112">2 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301958" class="clicky" aria-hidden="true">parent</a> | <a href="#47306867" class="clicky" aria-hidden="true">prev</a> | <a href="#47304264" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Rust is actually really unique among imperative languages in its general composability
<p>Can you compare it to some other imperative language? Because I really don't see anything particularly notable in Rust that would give it this property.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313462"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonask" class="hnuser">simonask</a> <a href="https://news.ycombinator.com/item?id=47313462">2 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47309112" class="clicky" aria-hidden="true">parent</a> | <a href="#47304264" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I’m mainly comparing to the progeny of C, where the biggest difference is the fact that almost everything is an expression in Rust.
<p>No need for ternary operators. C# unsafe blocks can only appear as statements (so you cannot delegate from a safe to an unsafe constructor, e.g.). C++ cannot return from the middle of an expression.</p>
<p>A related aspect is the type system, which composes with expressions in really interesting ways, so things like constant array sizes can be inferred.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304264"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lilyball" class="hnuser">lilyball</a> <a href="https://news.ycombinator.com/item?id=47304264">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301095" class="clicky" aria-hidden="true">parent</a> | <a href="#47301958" class="clicky" aria-hidden="true">prev</a> | <a href="#47301024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"View types" addresses one of the top pain points of the borrow checker, which is disjoint borrows on a single value. The compiler can understand values where only some fields are borrowed, so e.g. you can mutably borrow the currently-unborrowed fields, but there's no way to write these partial borrows and so you cannot write functions that either take or return these borrows. This often means having to restructure code to split up one struct into several child structs just to be able to borrow those substructs independently.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301024"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tensor" class="hnuser">tensor</a> <a href="https://news.ycombinator.com/item?id=47301024">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47295373" class="clicky" aria-hidden="true">parent</a> | <a href="#47301095" class="clicky" aria-hidden="true">prev</a> | <a href="#47302779" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">How are these suggestions not pragmatic? You don't <em>have</em> to use them, but if you need them they are there. From a security point of view I can see many of these being incredibly useful.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305211"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bigstrat2003" class="hnuser">bigstrat2003</a> <a href="https://news.ycombinator.com/item?id=47305211">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301024" class="clicky" aria-hidden="true">parent</a> | <a href="#47301447" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, that's not how it works. See for example async: I don't need it (and indeed hate working with it, because colored functions are incredibly unpleasant to work with). But a huge swath of libraries in the ecosystem are designed with the assumption that you will use it. If the language adds more features like the article is proposing, it will most likely balkanize the crate ecosystem even further. This stuff does affect people even if they never use the features in question.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301447"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=usrusr" class="hnuser">usrusr</a> <a href="https://news.ycombinator.com/item?id=47301447">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301024" class="clicky" aria-hidden="true">parent</a> | <a href="#47305211" class="clicky" aria-hidden="true">prev</a> | <a href="#47302779" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If it slows down Rust development it's not pragmatic. And if it creates a cultural schism between full commitment and pragmatic approaches, it's also trouble. Remember Scala?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304685"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tensor" class="hnuser">tensor</a> <a href="https://news.ycombinator.com/item?id=47304685">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301447" class="clicky" aria-hidden="true">parent</a> | <a href="#47302649" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;If it slows down Rust development it's not pragmatic.
<p>I truly don't understand. If you don't want rust to become complex, you don't want it to "develop" fast anyways. Unless you mean you think it will be slower to write code?</p>
<p>&gt; And if it creates a cultural schism between full commitment and pragmatic approaches, it's also trouble.</p>
<p>Zero clue what this is supposed to mean. WTF is "full commitment" here?</p>
<p>&gt; Remember Scala?</p>
<p>Scala, haskell, and others are high level languages in "academic terms." They have high levels of abstraction. The proposals are the opposite of high level abstractions, they instead formalize very important low level properties of code. If anything they <em>decrease</em> abstraction.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302649"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47302649">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301447" class="clicky" aria-hidden="true">parent</a> | <a href="#47304685" class="clicky" aria-hidden="true">prev</a> | <a href="#47302779" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust is nowhere near the complexity of Scala wrt. seemingly arbitrary high-level features. There's a <em>low-level</em>, <em>systems programming</em> featureset that involves quite a bit of complexity but that's also less arbitrary when comparing across similarly low-level languages.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302779"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=riffraff" class="hnuser">riffraff</a> <a href="https://news.ycombinator.com/item?id=47302779">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47295373" class="clicky" aria-hidden="true">prev</a> | <a href="#47300737" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; This may be too much advanced type theory for a useful language.
<p>I think a lot of things taken for granted these days were considered "too complicated" some time ago: think of how widespread pattern matching, closures, generics, or functional idioms in imperative languages are, and compare to e.g. Java 1.0.</p>
<p>My feeling is that the "acceptable level of complexity" for programming languages goes up over time, so probably stuff like effect types will be almost everywhere in another 10 years.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300737"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Ygg2" class="hnuser">Ygg2</a> <a href="https://news.ycombinator.com/item?id=47300737">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47302779" class="clicky" aria-hidden="true">prev</a> | <a href="#47301086" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; This may be too much advanced type theory for a useful language.
<p>Maybe but:</p>
<p>- Move fixes Pin</p>
<p>- Linear types, prevent memory leaks</p>
<p>- potentially effects simplify so many things</p>
<p>Each of these functionalities unlock capabilities people have complained about Rust. Namely async, gen blocks, memory leaks.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305653"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jibal" class="hnuser">jibal</a> <a href="https://news.ycombinator.com/item?id=47305653">2 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47300737" class="clicky" aria-hidden="true">parent</a> | <a href="#47301086" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes. The appalling level of ignorance in the comments here and failure to understand the article is disturbing and a little scary ... hopefully it won't get in the way of actually simplifying and unifying the language, generalizing special cases, removing limitations and roadblocks, etc. as outlined in the article.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301086"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=usrusr" class="hnuser">usrusr</a> <a href="https://news.ycombinator.com/item?id=47301086">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47300737" class="clicky" aria-hidden="true">prev</a> | <a href="#47300836" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Counterpoint: if any language could thrive in that valley of despair between pragmatic and theoretical excellence you're referring to, it would be Rust. Because so much of the cost is already paid for once you have satisfied the borrow checker. At least that's what I'd imagine, I could certainly be wrong.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300836"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dnautics" class="hnuser">dnautics</a> <a href="https://news.ycombinator.com/item?id=47300836">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47301086" class="clicky" aria-hidden="true">prev</a> | <a href="#47295442" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm not 100% convinced that "plugging memory error holes" was right at the compiler level.
<p>Currently building out clr, which uses a heuristic (not formal verification) method for checking soundness of zig code, using ~"refinement types". In principle one could build a more formal version of what I'm doing.</p>
<p><a href="https://github.com/ityonemo/clr" rel="nofollow">https://github.com/ityonemo/clr</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295442"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47295442">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47300836" class="clicky" aria-hidden="true">prev</a> | <a href="#47308226" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Boost is as actual as ever.
<p>Also the way nowadays is with constexpr, templates, and around the corner, static reflection.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308226"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=secondcoming" class="hnuser">secondcoming</a> <a href="https://news.ycombinator.com/item?id=47308226">2 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47295442" class="clicky" aria-hidden="true">prev</a> | <a href="#47301925" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Boost is stronger than ever.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301925"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Conscat" class="hnuser">Conscat</a> <a href="https://news.ycombinator.com/item?id=47301925">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">parent</a> | <a href="#47308226" class="clicky" aria-hidden="true">prev</a> | <a href="#47259148" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; I understand that Boost is now deprecated.
<p>Huh?? Boost is used basically everywhere.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304375"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jandrewrogers" class="hnuser">jandrewrogers</a> <a href="https://news.ycombinator.com/item?id=47304375">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301925" class="clicky" aria-hidden="true">parent</a> | <a href="#47303286" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Definitely not. Boost is specifically prohibited in many companies. I haven’t run into Boost in a source tree in over a decade.
<p>There are many reasons for this. Boost has uneven quality. Many of the best bits end up in the C++ standard. New versions sometimes introduce breaking changes. Recent versions of C++ added core language features that make many Boost library features trivial and clean to implement yourself. Boost can make builds much less pleasant. Boost comes with a lot of baggage.</p>
<p>Boost was a solution for when template metaprogramming in C++ was an arcane unmaintainable mess. Since then, C++ has intentionally made massive strides toward supporting template metaprogramming as a core feature that is qualitatively cleaner and more maintainable. You don’t really need a library like Boost to abstract those capabilities for the sake of your sanity.</p>
<p>If you are using C++20 or later, there isn’t much of a justification for using Boost these days.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303286"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Maxatar" class="hnuser">Maxatar</a> <a href="https://news.ycombinator.com/item?id=47303286">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">root</a> | <a href="#47301925" class="clicky" aria-hidden="true">parent</a> | <a href="#47304375" class="clicky" aria-hidden="true">prev</a> | <a href="#47259148" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not at all. Most of the good parts of boost are now part of the standard library, and the rest of boost that is of high quality have stand-alone implementations, like ASIO, pybind11 (which was heavily influenced by Boost.python), etc...
<p>A lot of the new stuff that gets added into boost these days is basically junk that people contribute because they want some kind of resume padding but that very few people actually use. Often times people just dump their library into boost and then never bother to maintain it thereafter.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47259148"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47259148">3 days ago</a> | <a href="#47295232" class="clicky" aria-hidden="true">prev</a> | <a href="#47303334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Reposting my comment from Reddit,
<p>I had some Scala 3 feelings when reading the vision, I hope Rust doesn't gets too pushy with type systems ideas.</p>
<p>That is how we end with other ecosystems doubling down in automatic memory management with a good enough ownership model for low level coding, e.g. Swift 6, OxCaml, Chapel, D, Linear Haskel, OCaml effects,...</p>
<p>Where the goal is that those features are to be used by experts, and everyone else stays on the confort zone.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302402"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palata" class="hnuser">palata</a> <a href="https://news.ycombinator.com/item?id=47302402">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">parent</a> | <a href="#47294726" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; I had some Scala 3 feelings when reading the vision, I hope Rust doesn't gets too pushy with type systems ideas.
<p>I don't know if it is true or not, but my feeling is that Scala brought a lot of new ideas. But as I read somewhere, "Scala was written by compiler people, to write compilers", and I can understand that feeling.</p>
<p>Kotlin came after Scala (I think?) and seems to have gotten a lot of inspiration from Scala. But somehow Kotlin managed to stay "not too complex", unlike Scala.</p>
<p>All that to say, Rust has been innovating in the zero-cost abstraction memory safe field. If it went the way of Scala, I wonder if another language could be "the Kotlin of Rust"? Or is that Zig already? (I have no idea about Zig)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302888"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hocuspocus" class="hnuser">hocuspocus</a> <a href="https://news.ycombinator.com/item?id=47302888">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47302402" class="clicky" aria-hidden="true">parent</a> | <a href="#47302678" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; But somehow Kotlin managed to stay "not too complex", unlike Scala.
<p>It's not really true anymore, Kotlin has slowly absorbed most of the same features and ideas even though they're sometimes pretty half-baked, and it's even less principled than the current Scala ecosystem. JetBrains also wants to make Kotlin target every platform under the sun.</p>
<p>At this point, the only notable difference are HKTs and Scala's metaprogramming abilities. Kotlin stuck to a compiler plugin exposing a standard interface (kotlinx.serialization) for compile-time codegen. Scala can do things like deriving an HTTP client from an OpenAPI specification on the fly, by the LSP backend.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302951"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palata" class="hnuser">palata</a> <a href="https://news.ycombinator.com/item?id=47302951">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47302888" class="clicky" aria-hidden="true">parent</a> | <a href="#47302678" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; JetBrains also wants to make Kotlin target every platform under the sun
<p>So did Scala long before. It's just that Kotlin got a lot more traction for different reasons.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303063"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hocuspocus" class="hnuser">hocuspocus</a> <a href="https://news.ycombinator.com/item?id=47303063">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47302951" class="clicky" aria-hidden="true">parent</a> | <a href="#47302678" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not to the same extent. Scala.JS and Kotlin.JS are somewhat comparable, other targets not so much. There was no serious attempt at making Scala target mobile devices, even during the window of opportunity with Scala on Android.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308035"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palata" class="hnuser">palata</a> <a href="https://news.ycombinator.com/item?id=47308035">2 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47303063" class="clicky" aria-hidden="true">parent</a> | <a href="#47302678" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; even during the window of opportunity with Scala on Android.
<p>I don't understand this. You can run any pure Java jar on Android, pretty sure you can do that with Scala too? It's not exactly a "different platform" in terms of programming language. Sure it needs tooling and specific libraries, but that's higher level than the programming language.</p>
<p>Jetbrains is doing interop with Swift (Kotlin -&gt; ObjC -&gt; Swift and more recently Kotlin -&gt; C -&gt; Swift), which Scala never did. But I don't really see how this is relevant in this conversation.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315044"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hocuspocus" class="hnuser">hocuspocus</a> <a href="https://news.ycombinator.com/item?id=47315044">2 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47308035" class="clicky" aria-hidden="true">parent</a> | <a href="#47302678" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can run Scala on Android and it's been done but it never worked well nor was given priority. Which is understandable as the commercial entities behind Scala already struggle to build the ecosystem and tooling in spaces where the language shines.
<p>For instance the Android runtime has chronically lagged behind mainline JVM bytecode versions, iirc once Scala started to emit Java 8 bytecode, Android was stuck on Java 6.</p>
<p>Kotlin had other obvious advantages on Android like its thin standard library or the inlining of higher-order functions.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302678"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47302678">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47302402" class="clicky" aria-hidden="true">parent</a> | <a href="#47302888" class="clicky" aria-hidden="true">prev</a> | <a href="#47294726" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; I wonder if another language could be "the Kotlin of Rust"?
<p>Some people would say that Swift is that language since it's potentially memory safe like Rust and is described as friendlier to novices. There's some room for disagreement wrt. the latter point.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302763"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palata" class="hnuser">palata</a> <a href="https://news.ycombinator.com/item?id=47302763">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47302678" class="clicky" aria-hidden="true">parent</a> | <a href="#47294726" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well many languages are memory safe. Java has been memory safe forever. Rust is the one that is memory-safe with zero-cost abstractions, right?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304747"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bombela" class="hnuser">bombela</a> <a href="https://news.ycombinator.com/item?id=47304747">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47302763" class="clicky" aria-hidden="true">parent</a> | <a href="#47294726" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust is also data race safe to boot.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294726"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294726">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">parent</a> | <a href="#47302402" class="clicky" aria-hidden="true">prev</a> | <a href="#47301948" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I doubt those languages would have the same level of traction as Rust, especially now that Rust has already gotten said traction over the past decade with even the Linux kernel using them. It's more likely that Rust will be written as today and then these extra features are added for more type safety in certain functions as like I said in another comment I doubt people are going to write type contracts for every single function (maybe LLMs will, but that's an orthogonal discussion).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295411"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47295411">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47294726" class="clicky" aria-hidden="true">parent</a> | <a href="#47301948" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Apparently you missed Swift.
<p>Linux kernel adoption of Rust hasn't been a smooth ride, exactly because of its type system among C folks.</p>
<p>It is only happening because the likes of Google and Microsoft want to see it through.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47297087"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47297087">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47295411" class="clicky" aria-hidden="true">parent</a> | <a href="#47301948" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Swift is not really for systems level programming like Rust and interestingly some projects like Ladybird have moved away from Swift towards Rust.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307254"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wolvesechoes" class="hnuser">wolvesechoes</a> <a href="https://news.ycombinator.com/item?id=47307254">2 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47297087" class="clicky" aria-hidden="true">parent</a> | <a href="#47306880" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Swift is not really for systems level programming
<p>Apple seems to think differently.</p>
<p>&gt; and interestingly some projects like Ladybird have moved away from Swift towards Rust.</p>
<p>Not really interesting after you spent some time tracking lifecycle of FOSS projects. I don't think it is a last "moving away" announcement we get from Ladybird.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306880"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306880">2 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47297087" class="clicky" aria-hidden="true">parent</a> | <a href="#47307254" class="clicky" aria-hidden="true">prev</a> | <a href="#47301948" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It certainly is for Apple, regardless of your opinion.
<p>It is all over the place in Swift documentation, WWDC sessions, and even last week on Meet the Team session, regarding on how to write safe systems programming code on Apple platforms.</p>
<p>Ladybird should focus on what language they actually want to deliver something.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301948"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Conscat" class="hnuser">Conscat</a> <a href="https://news.ycombinator.com/item?id=47301948">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">parent</a> | <a href="#47294726" class="clicky" aria-hidden="true">prev</a> | <a href="#47300768" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">My understanding is that Scala 3 came with many large breaking changes that made adoption difficult. I at least hadn't heard users complain that new features weren't desired.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300768"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Ygg2" class="hnuser">Ygg2</a> <a href="https://news.ycombinator.com/item?id=47300768">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">parent</a> | <a href="#47301948" class="clicky" aria-hidden="true">prev</a> | <a href="#47303334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Doubt Rust will ever get to implicit hell of Scala 2.
<p>If for anything, Rust isn't married to C as Scala is to Java.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306903"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306903">2 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47300768" class="clicky" aria-hidden="true">parent</a> | <a href="#47303334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It certainly is in what concerns ABI support, and dependency on LLVM.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307076"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Ygg2" class="hnuser">Ygg2</a> <a href="https://news.ycombinator.com/item?id=47307076">2 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">root</a> | <a href="#47306903" class="clicky" aria-hidden="true">parent</a> | <a href="#47303334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Scala had an unnatural dependency on Java, not JVM. I.e., imitating not just some patterns but copying its flawed interfaces. For example, Scala could express and bypass decades of cruft in the Java Collections API. Did it choose to do it?
<p>To paraphrase former Scala developer and present poker player, "If Java cut its nose, would you Scala... Oh god, stop! The blood, the blood!"</p>
<p>Everyone who wants to talk to low-level code has to have C ABI. The equivalent Scalaism in Rust would be if Rust reimplemented the C-inspired java.util.Date. Yes. Monday should be 0, not an enum. Because C did it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303334"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hardwaresofton" class="hnuser">hardwaresofton</a> <a href="https://news.ycombinator.com/item?id=47303334">3 days ago</a> | <a href="#47259148" class="clicky" aria-hidden="true">prev</a> | <a href="#47311526" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Really excited for the possibilities here.
<p>People undoubtedly thought going for Affine types was too much, and even simple things like null safety or enums-with-values and the prevalence of Result saw debate with minimalists voicing concerns.</p>
<p>A world where you could write a Rust program that is memory leak free with Affine types is one I want to live in. Haskell can do it now, but its just not easy and Rust has beat out Haskell with its mix of ML-strength types and practicality.</p>
<p>IMO these changes maintain Rusts winning mix of academia and practicality. Heres a proof point — dependent types weren't mentioned :)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306292"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hardwaresofton" class="hnuser">hardwaresofton</a> <a href="https://news.ycombinator.com/item?id=47306292">2 days ago</a> | <a href="#47303334" class="clicky" aria-hidden="true">parent</a> | <a href="#47311526" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">*linear types (the leak free future bit)
<p>This description is also a good crystallization of why one would want linear types</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311526"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=xorvoid" class="hnuser">xorvoid</a> <a href="https://news.ycombinator.com/item?id=47311526">2 days ago</a> | <a href="#47303334" class="clicky" aria-hidden="true">prev</a> | <a href="#47305910" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm pretty conflicted on this comment section. A lot of people are expressing a lot of fear of C++ bloat. I get that.
<p>I'm not sure what the right answer for Rust is, but I'm fairly convinced that these type system ideas are the future of programming languages.</p>
<p>Perhaps it can be added to rust in a reasonable and consistent way that doesn't ultimately feel like a kludgy language post-hoc bolt on. Time will tell. There is a serious risk to getting it wrong and making the language simply more complicated for no gain.</p>
<p>But, these ideas are really not obscure academic stuff. This is where programming language design is at. This moment is like talking about sum-types in the 2010s. These days that concept is normalized and expected in modern programming languages. But, that's a fairly recent development.</p>
<p>I suspect that Linear types, refinement types, etc will follow a similar trajectory. Whether new ideas like this can be reasonably added to existing languages in a good way is the age old question.</p>
<p>Hopefully Rust makes good choices on that road.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311734"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Levitating" class="hnuser">Levitating</a> <a href="https://news.ycombinator.com/item?id=47311734">2 days ago</a> | <a href="#47311526" class="clicky" aria-hidden="true">parent</a> | <a href="#47305910" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; There is a serious risk to getting it wrong and making the language simply more complicated for no gain.
<p>I think the Rust team/community is well-aware of this. Which is why Rust has such a well-defined RFC life-cycle.</p>
<p>At the other end, one of the biggest complaints about Rust is that many features seem eternally locked behind nightly feature gates.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312066"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=xorvoid" class="hnuser">xorvoid</a> <a href="https://news.ycombinator.com/item?id=47312066">2 days ago</a> | <a href="#47311526" class="clicky" aria-hidden="true">root</a> | <a href="#47311734" class="clicky" aria-hidden="true">parent</a> | <a href="#47305910" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I feel the same confliction about this organizational policy. It has been refreshing that they haven't just jammed half-baked ideas into stable like C++ has done for decades. But, yes, it's frustrating to bump into an issue and discover that a fix has been proposed and implemented but has never been moved to stable in 5-10 years. Some things feel like they're languishing in nightly forever.
<p>I don't personally have a solution to propose to this problem. I generally appreciate their caution and long-term considering. It's refreshing coming from C++. I suppose one could argue that they've overcorrected in the other direction. Unclear.</p>
<p>Deeper than that, I think there's a philosophical dispute on whether languages should or shouldn't even evolve. There are people with C-stability type thinking that would argue that long-term stability is so important that we should stop making changes and etch things into stone. There is some merit to that (a lot of unhelpful churn in modern programming). But, failure to modernize is eventually death IMHO. I think C is slowly dying because of exactly this. It will take quite a while because it is critical computing infrastructure. But, few people remain that defend it's viability. The arguments that remain are of the form "we simply don't have a viable replacement yet".</p>
<p>Perhaps you can even take the view that this is the lifecycle of programming languages. They're not supposed to live forever. That could be a reasonable take. But then you really have to confront the problem of code migration from old languages to new languages. That is a very very hard unsolved problem (e.g. see: COBOL).</p>
<p>Language evolution is foundationally a hard problem. And I'm not unhappy with Rust's approach. I think no one has managed to find an ideal approach.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305910"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=chadaustin" class="hnuser">chadaustin</a> <a href="https://news.ycombinator.com/item?id=47305910">2 days ago</a> | <a href="#47311526" class="clicky" aria-hidden="true">prev</a> | <a href="#47295988" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I write Rust for embedded systems and both effects and linear types would be meaningful improvements. Effects especially: if you have multiple cores in a coherent memory domain AND you run with interrupts enabled, you have to deal with three types of mutex:
<p>- data accessed by multiple cores and interrupt handlers must be modified under a spin lock and with interrupts disabled</p>
<p>- data accessed by multiple cores but not interrupt handlers only needs the spin lock</p>
<p>- data accessed by one core but maybe interrupt handlers only needs to pay for disabling interrupts</p>
<p>Depending on your core and how performance sensitive the code is, the costs of the above can vary significantly. It would be nice to encode these rules in the type system.</p>
<p>(Ordered types might be useful for “critical sections” — that is, areas where interrupts are disabled and the interrupt disablement guard absolutely must be dropped in order.)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295988"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pkal" class="hnuser">pkal</a> <a href="https://news.ycombinator.com/item?id=47295988">3 days ago</a> | <a href="#47305910" class="clicky" aria-hidden="true">prev</a> | <a href="#47303041" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">From the historical sources I could find online, it appears that Rust's borrow system was independently invented, or at least they don't mention linear logic or anything substructural. This is kind of interesting to me, especially given the reactions in this thread, and ties into the general difficulty of PL research to find acceptance among practitioners, especially when presented by researchers (which I think is regretful, I like the ideas in the article!). Perhaps we really should stick to terminology like "function colors" to make effect systems more popular (or not, because the color framing makes it sound bad to have different colors in a program, IIRC).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301492"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jltsiren" class="hnuser">jltsiren</a> <a href="https://news.ycombinator.com/item?id=47301492">3 days ago</a> | <a href="#47295988" class="clicky" aria-hidden="true">parent</a> | <a href="#47303299" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's the jargon, I think. PL research is in an awkward position, where the jargon is not shared with the much wider community of people using programming languages daily. From the other side, it looks like there is a small body of theoreticians using impenetrable language for discussing topics I'm supposed to be familiar with, because they are a core part of my day job. It's much easier to accept jargon, when it's used in a clearly separate field.
<p>Some of the terminology is just unfortunate. For example, I have an intuitive understanding of what a type means. The meaning used in PL theory is somehow wider, but I don't really understand how.</p>
<p>And then there is my pet peeve: side effect. Those should be effects instead, because they largely define the observable behavior of the program. Computation, on the other hand, is a side effect, to the extent it doesn't affect the observable behavior.</p>
<p>But then PL theory is using "effect" for something completely different. I don't know what exactly, but clearly not something I would consider an effect.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301743"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=voxl" class="hnuser">voxl</a> <a href="https://news.ycombinator.com/item?id=47301743">3 days ago</a> | <a href="#47295988" class="clicky" aria-hidden="true">root</a> | <a href="#47301492" class="clicky" aria-hidden="true">parent</a> | <a href="#47303299" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c9C">Man who uses arithmetic upset at research mathematicians for using words like R-module when they clearly do not mean a module in C++
<p>More at 11</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303299"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=egorelik" class="hnuser">egorelik</a> <a href="https://news.ycombinator.com/item?id=47303299">3 days ago</a> | <a href="#47295988" class="clicky" aria-hidden="true">parent</a> | <a href="#47301492" class="clicky" aria-hidden="true">prev</a> | <a href="#47305075" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't remember where I read it, but I think Rust cited Cyclone as an influence, a variation of C with "region-based" memory management - more or less the literature name for "lifetimes". I think Rust may be the first to use it directly for stack variables, however.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305075"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=DevelopingElk" class="hnuser">DevelopingElk</a> <a href="https://news.ycombinator.com/item?id=47305075">3 days ago</a> | <a href="#47295988" class="clicky" aria-hidden="true">parent</a> | <a href="#47303299" class="clicky" aria-hidden="true">prev</a> | <a href="#47303041" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Rust's discussion boards has an idea of "keyword generics" for expressing some of these concepts. The idea is that a function can be generic over const, async or some other keyworded effect. I like this description. It shows the benefits without too much theory.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303041"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jbritton" class="hnuser">jbritton</a> <a href="https://news.ycombinator.com/item?id=47303041">3 days ago</a> | <a href="#47295988" class="clicky" aria-hidden="true">prev</a> | <a href="#47258375" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">When I wrote my very first Rust code, I was trying to write to a socket. I got stuck on this task with misleading error messages for the longest time. I finally realized I had not made the socket object mutable. I’m used to Posix where you have an integer file descriptor and I don’t tend to think of socket write as a mutable operation. At least it doesn’t mutate state that my app manages. Perhaps something in the kernel gets mutated. I believe the socket interface may have been intended to support queuing which is perhaps why it needed to be mutable. I might have needed a lower level api. I just mention this because I think it’s interesting as to how it should be typed when mutation is external to the app. I didn’t follow through on using Rust and this was long ago so I’m sure some details are wrong.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304026"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=estebank" class="hnuser">estebank</a> <a href="https://news.ycombinator.com/item?id=47304026">3 days ago</a> | <a href="#47303041" class="clicky" aria-hidden="true">parent</a> | <a href="#47307858" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; got stuck on this task with misleading error messages for the longest time.
<p>Could you elaborate on that? We consider misleading error messages to be bugs and would like to know more on case we could fix them.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318244"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jbritton" class="hnuser">jbritton</a> <a href="https://news.ycombinator.com/item?id=47318244">2 days ago</a> | <a href="#47303041" class="clicky" aria-hidden="true">root</a> | <a href="#47304026" class="clicky" aria-hidden="true">parent</a> | <a href="#47307858" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It appears the error message has been improved.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307858"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=scottlamb" class="hnuser">scottlamb</a> <a href="https://news.ycombinator.com/item?id=47307858">2 days ago</a> | <a href="#47303041" class="clicky" aria-hidden="true">parent</a> | <a href="#47304026" class="clicky" aria-hidden="true">prev</a> | <a href="#47303737" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">`std::net::TcpStream`? Interestingly, it <em>doesn't</em> need to be mutable if you know the trick.
<p>* It implements `Write` for `TcpStream` which is likely what you were using. And `Write` requires `&amp;mut`, probably because the same trait is used for writing to application buffers (e.g. through `BufWriter` or just to a `Vec`). So this doesn't compile: [2] I think the error message is pretty good; maybe it's improved since you tried. It doesn't though suggest the trick below.</p>
<p>* It also implements `Write` for `&amp;TcpStream`. So if you use the awkward phrasing `(&amp;stream).write_all(b"asdf")`, you don't need mutable access. [3] This allows you to use it with anything that takes the trait, without requiring mutability. You might need this if say you're reading from the socket from one thread while simultaneously writing to it from another thread.</p>
<p>It's a vaguely similar situation with the most common async equivalent, `tokio::net::TcpStream`. The most straightforward way to write to it is with a trait that needs mutable access, but it is possible to write to a shared reference by not using a trait. They also have these `split` and `into_split` methods to get mutable access to something that implements the read traits and something that implements the write traits.</p>
<p>[1] <a href="https://doc.rust-lang.org/std/net/struct.TcpStream.html" rel="nofollow">https://doc.rust-lang.org/std/net/struct.TcpStream.html</a></p>
<p>[2] <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2024&amp;gist=eed09685aad16bc2296fc57df325a6d3" rel="nofollow">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;editio...</a></p>
<p>[2] <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2024&amp;gist=6b758520502f74ef04edbd2aa6bf6b46" rel="nofollow">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;editio...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303737"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=holden_nelson" class="hnuser">holden_nelson</a> <a href="https://news.ycombinator.com/item?id=47303737">3 days ago</a> | <a href="#47303041" class="clicky" aria-hidden="true">parent</a> | <a href="#47307858" class="clicky" aria-hidden="true">prev</a> | <a href="#47304675" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I also found it really unintuitive what needs to be made mutable. And still do to some degree.
<p>When I first had learned that rust had this concept of “opt-in” mutability, I thought that it must then be an accepted pattern that we make as little as possible be mutable in an attempt to help us better reason about the state of our program. I had come to rust after learning some clojure so I was like “ahh! Immutable by default! So everything’s a value!”</p>
<p>But in reality it feels like rust code is not “designed” around immutability but instead around appeasing the borrow checker - which is actually pretty easy to reason about once you get the hang of the language. But it’s a ton to learn up front</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304675"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=undeveloper" class="hnuser">undeveloper</a> <a href="https://news.ycombinator.com/item?id=47304675">3 days ago</a> | <a href="#47303041" class="clicky" aria-hidden="true">parent</a> | <a href="#47303737" class="clicky" aria-hidden="true">prev</a> | <a href="#47258375" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think part of it might be just that for modeling's sake it makes it clear when something can write vs only read the socket</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47258375"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47258375">3 days ago</a> | <a href="#47303041" class="clicky" aria-hidden="true">prev</a> | <a href="#47304724" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Finally seeing more movement on effects or what started as keyword generics, there was a big blog post a few years ago but not much public facing news although of course they've been working on it as Yoshua says in the post.
<p>I truly do wish we get closer to Ada and even Lean in terms of safety, would be great to see all these theoretical type system features become reality. I use the `anodized` crate right now for refinement type features, and who knows, maybe we get full fledged dependent types too as there aren't many production languages with them and certainly not popular languages.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304724"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=undeveloper" class="hnuser">undeveloper</a> <a href="https://news.ycombinator.com/item?id=47304724">3 days ago</a> | <a href="#47258375" class="clicky" aria-hidden="true">prev</a> | <a href="#47309469" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm not sure why people are so deeply scared. these are all pretty neat features for people who will need them (off rip seemingly mostly in the embedded world). It's not like the inclusion of these forces you to use them — I've never had to deal with unsafe rust for shipping web stuff, and I highly doubt I'd have to deal with most of these. For modeling's sake it would be nice to have pattern types and view types, I can see them being useful</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305479"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47305479">2 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">parent</a> | <a href="#47304839" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">People will push this crap into production codebases and link to these articles when you say you don’t want complexity. Best way to manage is to not make it possible, like go.
<p>You indirectly deal with this kind of thing when compiling web server code too. It compiles super slow and can have weird errors. This is because the people who build the web stack in rust used a million traits/generics/macros etc.</p>
<p>Even if you look at something like an io_uring library in rust, it uses a bunch of macros instead of just repeating 3 lines of code.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305833"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=anon291" class="hnuser">anon291</a> <a href="https://news.ycombinator.com/item?id=47305833">2 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">root</a> | <a href="#47305479" class="clicky" aria-hidden="true">parent</a> | <a href="#47304839" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">3 lines of code that may need to change is much more complex than a macro that signals intent.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306329"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47306329">2 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">root</a> | <a href="#47305833" class="clicky" aria-hidden="true">parent</a> | <a href="#47304839" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><a href="https://docs.rs/io-uring/latest/io_uring/opcode/index.html" rel="nofollow">https://docs.rs/io-uring/latest/io_uring/opcode/index.html</a>
<p>You can click the source code link and read the code here. Macros aren’t needed at all if every single operation isn’t a different type.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304839"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simplesocieties" class="hnuser">simplesocieties</a> <a href="https://news.ycombinator.com/item?id=47304839">3 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">parent</a> | <a href="#47305479" class="clicky" aria-hidden="true">prev</a> | <a href="#47309469" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This was the <em>exact</em> same argument used to push new c++ features and look where the language is now.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308103"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gpderetta" class="hnuser">gpderetta</a> <a href="https://news.ycombinator.com/item?id=47308103">2 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">root</a> | <a href="#47304839" class="clicky" aria-hidden="true">parent</a> | <a href="#47307961" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">you mean better than ever?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307961"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=devnullbrain" class="hnuser">devnullbrain</a> <a href="https://news.ycombinator.com/item?id=47307961">2 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">root</a> | <a href="#47304839" class="clicky" aria-hidden="true">parent</a> | <a href="#47308103" class="clicky" aria-hidden="true">prev</a> | <a href="#47309469" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">...a far better place than 2011.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309469"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=umanwizard" class="hnuser">umanwizard</a> <a href="https://news.ycombinator.com/item?id=47309469">2 days ago</a> | <a href="#47304724" class="clicky" aria-hidden="true">prev</a> | <a href="#47307079" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; In formal terms, Rust’s type system is considered affine, which means that each value must be used at most once. And “use at most once” is exactly what’s needed to guarantee the absence of bugs like “use after free”.
<p>&gt; But there are type systems which can provide even more guarantees. One step beyond “use at most once” is “use exactly once”. Types that provide that guarantee are called “linear” and in addition to guaranteeing the absence of “use after free” they can also guarantee the absence of memory leaks.</p>
<p>Does anyone know why these are called “affine” and “linear”, respectively? What’s the analogy, if any, to the use of those terms in math? (E.g. an affine transformation of vector spaces)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307079"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ismailmaj" class="hnuser">ismailmaj</a> <a href="https://news.ycombinator.com/item?id=47307079">2 days ago</a> | <a href="#47309469" class="clicky" aria-hidden="true">prev</a> | <a href="#47308671" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Surprised with the push back of the comments, getting effects on Rust would be a dream.
<p>Could even enable some stuff like passing loggers around not by parameters but by effect.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308671"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=theknarf" class="hnuser">theknarf</a> <a href="https://news.ycombinator.com/item?id=47308671">2 days ago</a> | <a href="#47307079" class="clicky" aria-hidden="true">prev</a> | <a href="#47301411" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm surprised by the backlash in the comment section here, all of these things seems like the obvious next step for Rust. It seem people are scared of big words?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310397"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hu3" class="hnuser">hu3</a> <a href="https://news.ycombinator.com/item?id=47310397">2 days ago</a> | <a href="#47308671" class="clicky" aria-hidden="true">parent</a> | <a href="#47301411" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">&gt; It seem people are scared of big words?
<p>Classic "skill issue" hubris by the language community.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301411"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wewewedxfgdf" class="hnuser">wewewedxfgdf</a> <a href="https://news.ycombinator.com/item?id=47301411">3 days ago</a> | <a href="#47308671" class="clicky" aria-hidden="true">prev</a> | <a href="#47305213" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No-one ever has the "Grand Vision" to cut something down to it's essential 25% and delete the rest.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305872"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=chiffaa" class="hnuser">chiffaa</a> <a href="https://news.ycombinator.com/item?id=47305872">2 days ago</a> | <a href="#47301411" class="clicky" aria-hidden="true">parent</a> | <a href="#47305637" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can't cut down a language without breaking changes. And there fairly often are internal changes to simplify the compiler and the tooling. Just in the latest release, annotation internals were finally fully unified between rustc, cargo, clippy and other tools. This was a fairly considerable effort in deduplicating code. Borrow checker is being rewritten to move to tree borrows, trait resolution is being refactored for a variety of reasons. Code is being simplified where possible, but this doesn't mean Rust doesn't have areas to improve in, especially if there is a goal of replacing Ada/SPARK</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305637"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lioeters" class="hnuser">lioeters</a> <a href="https://news.ycombinator.com/item?id=47305637">2 days ago</a> | <a href="#47301411" class="clicky" aria-hidden="true">parent</a> | <a href="#47305872" class="clicky" aria-hidden="true">prev</a> | <a href="#47304332" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Unless there's a conscious and constant effort to keep things simple, a programming language or software project will grow to consume all available resources, developers' time, intellectual capacity, and funding.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304332"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=techbrovanguard" class="hnuser">techbrovanguard</a> <a href="https://news.ycombinator.com/item?id=47304332">3 days ago</a> | <a href="#47301411" class="clicky" aria-hidden="true">parent</a> | <a href="#47305637" class="clicky" aria-hidden="true">prev</a> | <a href="#47318965" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">By all means, write some Go instead—you might want to order a new `if err != nil` button to stave off the RSI. The rest of us are trying to make things better.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318965"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nsm" class="hnuser">nsm</a> <a href="https://news.ycombinator.com/item?id=47318965">2 days ago</a> | <a href="#47301411" class="clicky" aria-hidden="true">parent</a> | <a href="#47304332" class="clicky" aria-hidden="true">prev</a> | <a href="#47304837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><a href="https://without.boats/blog/revisiting-a-smaller-rust/" rel="nofollow">https://without.boats/blog/revisiting-a-smaller-rust/</a>
<p>I think there is a programming language hole for a Rust-like language, but with GC and green threads. One that dispenses with single-ownership, and async/await footguns.</p>
<p>Something like F#/Kotlin is closest in terms of developer experience.</p>
<p>Unfortunately, we are really lacking a language that skews badly on some other axis</p>
<p>- F# - tainted by being Windows only for really long and being Microsoft. - Kotlin - tainted by the JVM - Java 24+ - has virtual threads, sum types, match expressions and other niceties, but tainted by the JVM again (Verbosity included, but this is not really a factor with IDEs and LLMs.)</p>
<p>Note that the opinions above are not mine, but "consensus". I'd say they are all unfair opinions.</p>
<p>I feel like people end up favoring new languages, simply because of novelty. Like, inevitably, somebody is gonna say Gleam. I'm all for having existing BEAM users getting access to new languages, but I'm not sure why one would pick a BEAM language for non-server applications when the developer tooling story for CLI apps, line-of-business apps and so on is so much stronger for the .NET and JVM ecosystems. No offense to the Gleam folks intended.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47304837"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ebiederm" class="hnuser">ebiederm</a> <a href="https://news.ycombinator.com/item?id=47304837">3 days ago</a> | <a href="#47301411" class="clicky" aria-hidden="true">parent</a> | <a href="#47318965" class="clicky" aria-hidden="true">prev</a> | <a href="#47305213" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Chuck Moore of Forth fame.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305213"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bionhoward" class="hnuser">bionhoward</a> <a href="https://news.ycombinator.com/item?id=47305213">3 days ago</a> | <a href="#47301411" class="clicky" aria-hidden="true">prev</a> | <a href="#47309591" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">gotta admit i groaned a bit at this because it would make rust more complicated, but on my 2nd read i realized:
<p>- some things (compile time bounds checking tensor shapes) are hard / impossible to implement now; "pattern types" could be great for that</p>
<p>- however "no panic" is already handled by clippy, might not be much uplift for doing that at a type level.</p>
<p>my 2c: it's great to be excited and brainstorm, some of these ideas might be gold. conveying the benefit is key. it would be good to focus on stuff for which rust doesn't already have a workable solution. i like the pattern types, the rest would take convincing</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309591"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=room271" class="hnuser">room271</a> <a href="https://news.ycombinator.com/item?id=47309591">2 days ago</a> | <a href="#47305213" class="clicky" aria-hidden="true">prev</a> | <a href="#47303222" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust needs to be careful that it doesn't invite the type-programming crowd in too much. Even if individual features are helpful, the cultural effect on the programming language in terms of the community (i.e. libraries and idioms) can really fragment and destroy a language. Scala, which I programmed in for many years, is a good example -- lots of great features but ultimately overwhelmed by typesafe abstractions that held theoretical appeal but hampered readability and fragmented the community. (Lack of backwards compatibility and poor tooling also hurt Scala no doubt about it, just as slow compile times hurt Rust.)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303222"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=esafak" class="hnuser">esafak</a> <a href="https://news.ycombinator.com/item?id=47303222">3 days ago</a> | <a href="#47309591" class="clicky" aria-hidden="true">prev</a> | <a href="#47310983" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">These would be great additions. I don't get why people don't want powerful type systems. Let the language work for you!</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310983"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nmilo" class="hnuser">nmilo</a> <a href="https://news.ycombinator.com/item?id=47310983">2 days ago</a> | <a href="#47303222" class="clicky" aria-hidden="true">prev</a> | <a href="#47320875" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust is the wrong language for effects ironically <em>because</em> of its strict typing. They would probably decide that all effects have to be specified on every function or that any change in capabilities is a breaking change. Which is safest, but horrible for dev ex. Whereas Go most people would just be like “yeah, Hyrum’s law, sorry I broke your weird effect consumer, I don’t really care.”</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320875"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=baroudi" class="hnuser">baroudi</a> <a href="https://news.ycombinator.com/item?id=47320875">1 day ago</a> | <a href="#47310983" class="clicky" aria-hidden="true">prev</a> | <a href="#47322812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Introducing more colors (or effects) without a way to abstract over them will cause a lot of issues. It is already painful to work with async, one have to either accept a lot of code duplication or to perform some obscure black magic with the macro system.
<p>Also, the language is already inelegant with each monad having its own syntactic sugar (result, option and async).</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322812"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jk-pasha" class="hnuser">jk-pasha</a> <a href="https://news.ycombinator.com/item?id=47322812">1 day ago</a> | <a href="#47320875" class="clicky" aria-hidden="true">prev</a> | <a href="#47294527" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There’s one other way to look at it - in the age of vibe coding it makes sense to make the language more safe. Easier for the AI not to shoot itself in the foot.
<p>But we’re gonna need better tools for reading this new denser code packed with gotchas. That’s for sure.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294527"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jadenPete" class="hnuser">jadenPete</a> <a href="https://news.ycombinator.com/item?id=47294527">3 days ago</a> | <a href="#47322812" class="clicky" aria-hidden="true">prev</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I couldn’t disagree more. Most of my company’s backend code is written in Scala, and most of our engineers dislike it because the language is difficult to understand, has way too many features, and has many ways to solve the same problem. I don’t want Rust to continue down this path, and I already worry with some of the syntactic sugar and type system additions being discussed that it already has.
<p>A language’s type system doesn’t need to model every possible type of guarantee. It just needs to provide a type safe way to do 95% of things and force its users to conform to use the constructs it provides. Otherwise it becomes a buggy hodge podge of features that interact in poor and unpredictable ways. This is already the case in Scala; we’ve discovered almost 20 bugs in the compiler in the past year.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308727"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=theknarf" class="hnuser">theknarf</a> <a href="https://news.ycombinator.com/item?id=47308727">2 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">parent</a> | <a href="#47294707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; A language’s type system doesn’t need to model every possible type of guarantee
<p>Actually this is the exact point of a type system. Why would you want to write unit tests for stuff the compiler can guarantee for you at the type system level?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294707"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294707">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">parent</a> | <a href="#47308727" class="clicky" aria-hidden="true">prev</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There is a middle ground. People seem to use Haskell and OCaml just fine and both are as expressive, so maybe it is just Scala having shoved in too many things. Based on what the article shows, it doesn't seem like they're making ten different ways to do the same thing but rather one way to (optionally) get more type safety out. I doubt everyone will be writing dependent type contracts for every single function, it's more for certain pieces of the codebase.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294768"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=MrBuddyCasino" class="hnuser">MrBuddyCasino</a> <a href="https://news.ycombinator.com/item?id=47294768">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">root</a> | <a href="#47294707" class="clicky" aria-hidden="true">parent</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Ah yes Haskell, the reasonable centrist position in language design.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294821"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294821">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">root</a> | <a href="#47294768" class="clicky" aria-hidden="true">parent</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Compared to the other languages listed in this thread, it definitely is, and it has production systems unlike them.
<p><a href="https://news.ycombinator.com/item?id=47259148">https://news.ycombinator.com/item?id=47259148</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295253"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=MrBuddyCasino" class="hnuser">MrBuddyCasino</a> <a href="https://news.ycombinator.com/item?id=47295253">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">root</a> | <a href="#47294821" class="clicky" aria-hidden="true">parent</a> | <a href="#47295418" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You got a point there.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295418"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47295418">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">root</a> | <a href="#47294821" class="clicky" aria-hidden="true">parent</a> | <a href="#47295253" class="clicky" aria-hidden="true">prev</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Ever heard of Apple, Facebook, Jane Street, HP?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302815"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=timcobb" class="hnuser">timcobb</a> <a href="https://news.ycombinator.com/item?id=47302815">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">root</a> | <a href="#47295418" class="clicky" aria-hidden="true">parent</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think they were saying haskell is a production language</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306922"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306922">2 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">root</a> | <a href="#47302815" class="clicky" aria-hidden="true">parent</a> | <a href="#47294514" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">They were downplaying the other examples.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294514"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=arrty88" class="hnuser">arrty88</a> <a href="https://news.ycombinator.com/item?id=47294514">3 days ago</a> | <a href="#47294527" class="clicky" aria-hidden="true">prev</a> | <a href="#47305389" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I would love to have a use case to learn and write rust today. But i am deep in node and go services for my employer. Previously wrote java and c#. What are people writing in rust today?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294904"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=TeamDman" class="hnuser">TeamDman</a> <a href="https://news.ycombinator.com/item?id=47294904">3 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">parent</a> | <a href="#47295707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I use Rust for command line applications.
<p>I find that CLI is a great way to model problems. When I find myself doing something that has graduated beyond a comfortable amount of PowerShell, Rust is there for me.</p>
<p>I have a template I've been evolving so it's super easy to get started with something new; I just copy the template and slam Copilot with some rough ideas on what I want and it works out.</p>
<p><a href="https://github.com/teamdman/teamy-rust-cli" rel="nofollow">https://github.com/teamdman/teamy-rust-cli</a></p>
<p>Just today used it to replace a GitHub stats readme svg generator thing that someone else made that was no longer working properly.</p>
<p><a href="https://github.com/TeamDman/teamy-github-readme-stats" rel="nofollow">https://github.com/TeamDman/teamy-github-readme-stats</a></p>
<p>Decomposes the problem very nicely into incrementally achievable steps</p>
<p>1. `fetch &lt;username&gt;` to get info from github into a cache location 2. `generate &lt;username&gt; &lt;output.svg&gt;` to load stats and write an svg 3. `serve` to run a webserver to accept GET requests containing the username to do the above</p>
<p>Means that my stuff always has `--help` and `--version` behaviours too</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295707"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=raphinou" class="hnuser">raphinou</a> <a href="https://news.ycombinator.com/item?id=47295707">3 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">parent</a> | <a href="#47294904" class="clicky" aria-hidden="true">prev</a> | <a href="#47295724" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm working on a multisig sign-off solution, with the first use case being file downloads like GitHub releases authentication: <a href="https://github.com/asfaload/asfaload" rel="nofollow">https://github.com/asfaload/asfaload</a>
<p>I'm coming from F# and find rust a good compromise: great type safety (though I prefer the F# language) with an even better ecosystem. It can also generate decently sized statically compiled executables, useful for CLI tools, and the library code I wrote should be available to mobile apps (to be developed).</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295724"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ChadNauseam" class="hnuser">ChadNauseam</a> <a href="https://news.ycombinator.com/item?id=47295724">3 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">parent</a> | <a href="#47295707" class="clicky" aria-hidden="true">prev</a> | <a href="#47307286" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm having fun using it to make websites. Rust→WASM works really well. Definitely a very enjoyable way to make web apps. I've been trying to think how I can contribute to the ecosystem, seeing as I enjoy it so much. Rust gives you a control over memory that is impossible to replicate in javascript, and which allows much more performant code</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307286"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wolvesechoes" class="hnuser">wolvesechoes</a> <a href="https://news.ycombinator.com/item?id=47307286">2 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">parent</a> | <a href="#47295724" class="clicky" aria-hidden="true">prev</a> | <a href="#47294688" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; What are people writing in rust today?
<p>Rewriting existing code for karma points and GitHub stars. Plus some minority actually trying to build something new.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294688"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294688">3 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">parent</a> | <a href="#47307286" class="clicky" aria-hidden="true">prev</a> | <a href="#47309836" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Whatever I used to use Node for, like web servers, I now use Rust. It's pretty nice, with a strong OCaml-like type system which I've used before (better than TypeScript even in some cases), plus it's much faster and more memory efficient such that I can run way more services on my 5 dollar Hetzner box with Dokploy compared to Node or Java or C#.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309836"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lsuresh" class="hnuser">lsuresh</a> <a href="https://news.ycombinator.com/item?id=47309836">2 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">parent</a> | <a href="#47294688" class="clicky" aria-hidden="true">prev</a> | <a href="#47305389" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">We built Feldera's engine in Rust: <a href="https://github.com/feldera/feldera" rel="nofollow">https://github.com/feldera/feldera</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305389"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Surac" class="hnuser">Surac</a> <a href="https://news.ycombinator.com/item?id=47305389">3 days ago</a> | <a href="#47294514" class="clicky" aria-hidden="true">prev</a> | <a href="#47309800" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I do not write Rust. I have left c++ cause of the feature creep of the last years that made it even harder to read c++. Reading code is so important. Make language not unfriendly for readers and value the time people put into learning a language. I have seen many c++ programmers leaving cause they feel its an other language now</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309800"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lsuresh" class="hnuser">lsuresh</a> <a href="https://news.ycombinator.com/item?id=47309800">2 days ago</a> | <a href="#47305389" class="clicky" aria-hidden="true">prev</a> | <a href="#47308705" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There are some solid ideas here and would definitely apply to the IVM engine we're building. I'm curious if some of these effects could play a role in faster rust compilation times (e.g. nopanic..)?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308705"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kpcyrd" class="hnuser">kpcyrd</a> <a href="https://news.ycombinator.com/item?id=47308705">2 days ago</a> | <a href="#47309800" class="clicky" aria-hidden="true">prev</a> | <a href="#47294466" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I just want to be able to call Default::default() from within const {}</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309013"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=estebank" class="hnuser">estebank</a> <a href="https://news.ycombinator.com/item?id=47309013">2 days ago</a> | <a href="#47308705" class="clicky" aria-hidden="true">parent</a> | <a href="#47294466" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's on the way. Already available in nightly for select types.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294466"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47294466">3 days ago</a> | <a href="#47308705" class="clicky" aria-hidden="true">prev</a> | <a href="#47305968" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This sounds insane at this point. The language already has too many features. Would be cool if all these people with amazing visions could move it elsewhere.
<p>Rust is fast tracking being as bad as c++ in terms of just garbage in it.</p>
<p>IMO the worst thing about c++ isn't that it is unsafe but it is extemely difficult to learn to a satisfying degree.</p>
<p>This is already kind of feels true for Rust and it will be surely true if people just keep shoving their amazing ideas into it.</p>
<p>IMO even async/tokio/error-handling aren't that well though out in rust. So much for keeping things out of the language.</p>
<p>Maybe Rust just wasn't what I wanted and I am salty about it but it feels a bit annoying when I see posts like this and considering where Rust is now after many years of shoving stuff into it</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294616"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47294616">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47294669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; The language already has too many features.
<p>That's actually the point. Many of these additions can be phrased as <em>unifying</em> existing features and allowing them to be used in previously unusable ways and contexts. There's basically no real increase in user-perceived complexity. The Rust editions system is a key enabler of this, and C++ has nothing comparable.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295403"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47295403">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294616" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It has clang tidy, -std=lang-version, and preprocessor that is version aware.
<p>Rust editions don't cover all use cases that one can think of regarding language evolution, and requires full access to source code.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47296376"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=SkiFire13" class="hnuser">SkiFire13</a> <a href="https://news.ycombinator.com/item?id=47296376">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47295403" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; requires full access to source code
<p>What do you mean? Editions don't require full access to source code. Rust in general relies heavily on having access to source code, but that has nothing to do with how editions work</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47296729"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47296729">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47296376" class="clicky" aria-hidden="true">parent</a> | <a href="#47296905" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can write a binary library that exposes a C ABI using Rust (which is indistinguishable from an ordinary C/C++ library) and then provide source for a Rust wrapper crate that provides a "safe" interface to it, much like a C header file.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47296905"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47296905">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47296376" class="clicky" aria-hidden="true">parent</a> | <a href="#47296729" class="clicky" aria-hidden="true">prev</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes they do, when mixing crates from various editions and how changes interact together.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47298240"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47298240">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47296905" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; when mixing crates from various editions and how changes interact together.
<p>Could you elaborate more on this? It's not obvious to me right now why (for example) Crate A using the 2024 edition and Crate B using the 2015 edition would require both full access to both crates' source beyond the standard lack of a stable ABI.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47299500"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47299500">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47298240" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Because in order to have standard library breaking changes across editions, if those types are exposed in the crate public types, or change their semantics across editions, the compiler has to be able to translate between them when generating code.
<p>See the Rust documentation on what editions are allowed to change, and the advanced migration guide on examples regarding manual code migration.</p>
<p>Not so much what has happened thus far, rather the limitations imposed in what is possible to actually break across editions.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300729"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Rusky" class="hnuser">Rusky</a> <a href="https://news.ycombinator.com/item?id=47300729">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47299500" class="clicky" aria-hidden="true">parent</a> | <a href="#47301069" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Or put another way, a hypothetical feature that you made up in your head is the thing that requires source access. Editions do not let you change the semantics of types.
<p>To be fair, Rust tooling does tend toward build-from-source. But this is for completely different reasons than the edition system: if you had a way to build a crate and then feed the binary into builds by future compilers, it would require zero additional work to link it into a crate using a different edition.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302242"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47302242">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47300729" class="clicky" aria-hidden="true">parent</a> | <a href="#47301069" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Exactly, hence why people should stop talking about editions as if they sort out all Rust evolution problems, in your own words it doesn't allow changing type semantics</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302910"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ChrisSD" class="hnuser">ChrisSD</a> <a href="https://news.ycombinator.com/item?id=47302910">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47302242" class="clicky" aria-hidden="true">parent</a> | <a href="#47301069" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think you're too stuck on the current implementation. Work is going into investigating how to evolve the standard library over editions. The "easiest" win would be to have a way to do edition-dependent re-exports of types.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306940"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="400" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306940">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47302910" class="clicky" aria-hidden="true">parent</a> | <a href="#47301069" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What I am stuck is Rust folks advocating editions as the solution for everything in language evolution, when it clearly isn't.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301069"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47301069">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47299500" class="clicky" aria-hidden="true">parent</a> | <a href="#47300729" class="clicky" aria-hidden="true">prev</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What you're describing sounds more like a <em>potential</em> issue with editions if/when they allow breaking stdlib changes more than a problem with editions as they exist today, which is more what I took the original comment to be talking about.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302245"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47302245">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47301069" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Exactly because they don't allow it, they don't cover all scenarios regarding language evolution</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302972"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47302972">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47302245" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">OK, sure, but again what breaking changes editions do/don't currently allow is independent from what SkiFire13/I was responding to, which was the "requires full access to source code" bit.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306950"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="400" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306950">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47302972" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">How do you expect a compiler to be able to mix and match changes across editions between crates, if those happen to be changes in semantic behaviour?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309193"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="440" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47309193">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47306950" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Depends on the change. Obviously the compiler doesn't need to care about cross-edition compatibility between crates if the changes in question don't impact the public API. Otherwise, I'd expect the compiler to canonicalize the changes, and from what I understand that is precisely how edition changes are chosen/designed/implemented.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300707"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=patrick451" class="hnuser">patrick451</a> <a href="https://news.ycombinator.com/item?id=47300707">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294616" class="clicky" aria-hidden="true">parent</a> | <a href="#47295403" class="clicky" aria-hidden="true">prev</a> | <a href="#47306229" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This comparison is useless until rust commits to a stable ABI.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306229"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hrmtst93837" class="hnuser">hrmtst93837</a> <a href="https://news.ycombinator.com/item?id=47306229">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294616" class="clicky" aria-hidden="true">parent</a> | <a href="#47300707" class="clicky" aria-hidden="true">prev</a> | <a href="#47295635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Unifying surface features increases the combinatorics of interactions between traits, lifetimes, generics, specialization, and macros and leads to surprising edge cases.
<p>Editions buy migration safety and let the standard evolve, but they do not shrink the mental model newcomers must carry and they force tooling and libraries to support multiple modes at once, which is a different kind of maintenance tax than evolving C++ compilers and feature test macros impose.</p>
<p>Require RFCs to include an interaction test matrix, compile time and code size measurements, and a pass from rust-analyzer and clippy so ergonomics regressions are visible before users hit them.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306660"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47306660">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47306229" class="clicky" aria-hidden="true">parent</a> | <a href="#47295635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; and they force [] libraries to support multiple modes at once,
<p>I'm not entirely sure I agree? I don't think any library except for the standard library needs to "support multiple modes at once"; everything else just sets its own edition and can remain blissfully unaware of whatever edition its downstream consumer(s) are using.</p>
<p>&gt; which is a different kind of maintenance tax than evolving C++ compilers and feature test macros impose.</p>
<p>I'm not sure I agree here either? Both Rust and C/C++ tooling and their standard libraries needs to support multiple "modes" due to codebases not all using the same "mode", so to me the maintenance burden should be (abstractly) the same for the two.</p>
<p>&gt; Require RFCs to include an interaction test matrix, compile time and code size measurements, and a pass from rust-analyzer and clippy</p>
<p>IIRC rustc already tracks various compilation-related benchmarks at perf.rust-lang.org. rustc also has edition-related warnings [0] (see the rust-YYYY-compatibility groups), so you don't even need clippy/rust-analyzer.</p>
<p>[0]: <a href="https://doc.rust-lang.org/rustc/lints/groups.html" rel="nofollow">https://doc.rust-lang.org/rustc/lints/groups.html</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307198"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hrmtst93837" class="hnuser">hrmtst93837</a> <a href="https://news.ycombinator.com/item?id=47307198">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47306660" class="clicky" aria-hidden="true">parent</a> | <a href="#47295635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In practice library authors must consider the editions used by downstream crates because public APIs cross crate boundaries. Even if a crate compiles under a single edition, exported APIs often avoid edition specific idioms that could cause friction for consumers compiled under older editions. This leads to a conservative design style where libraries effectively target the lowest common denominator of the ecosystem. The result is that authors informally maintain compatibility across editions even if the compiler technically allows them to ignore downstream edition choices.
<p>Large Rust organizations often run mixed-edition workspaces because upgrading hundreds of crates simultaneously is impractical. Libraries in the workspace therefore interact across editions during migration periods. So while technically each crate chooses its edition, ecosystem reality introduces cross-edition friction.</p>
<p>Feature test macros in C and C++ primarily gate access to optional APIs or compiler capabilities. Rust editions can change language semantics rather than merely enabling features. Examples include changes to module path resolution, trait object syntax requirements such as dyn, or additions to the prelude. Semantic differences influence parsing, name resolution, and type checking in ways that exceed the scope of a conditional feature macro.</p>
<p>Tooling complexity is structurally different. Rust tools such as rustc, rust analyzer, rustfmt, and clippy must understand edition dependent grammar and semantics simultaneously. The tooling stack therefore contains logic branches for multiple language modes. In contrast, feature test macros generally affect conditional compilation paths inside user code but do not require parsers or analysis tools to support different core language semantics.</p>
<p>Rust promises permanent support for previous editions, which implies that compiler infrastructure must preserve older semantics indefinitely. Over time this creates a cumulative maintenance burden similar to maintaining compatibility with many historical language versions.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309091"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aw1621107" class="hnuser">aw1621107</a> <a href="https://news.ycombinator.com/item?id=47309091">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47307198" class="clicky" aria-hidden="true">parent</a> | <a href="#47295635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Even if a crate compiles under a single edition, exported APIs often avoid edition specific idioms that could cause friction for consumers compiled under older editions.
<p>Do you have some concrete examples of this outside the expected bump to the minimum required Rust version? I'm coming up blank, and this sounds like it goes against one of the primary goals of editions (i.e., <em>seamless</em> interop) as well.</p>
<p>&gt; So while technically each crate chooses its edition, ecosystem reality introduces cross-edition friction.</p>
<p>And this is related to the above; I can't think of any actual sources of friction in a mixed-edition project beyond needing to support new-enough rustc versions.</p>
<p>&gt; Rust tools such as rustc, rust analyzer, rustfmt, and clippy must understand edition dependent grammar and semantics simultaneously.</p>
<p>I'm not entirely convinced here? Editions are a crate-wide property and crates are Rust's translation units, so I don't think there should be anything more "simultaneous" going on compared to -std=c++xx/etc. flags.</p>
<p>&gt; Over time this creates a cumulative maintenance burden similar to maintaining compatibility with many historical language versions.</p>
<p>Sure, but that's more or less what I was saying in the first place!</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295635"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jstanley" class="hnuser">jstanley</a> <a href="https://news.ycombinator.com/item?id=47295635">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294616" class="clicky" aria-hidden="true">parent</a> | <a href="#47306229" class="clicky" aria-hidden="true">prev</a> | <a href="#47294669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><a href="https://xkcd.com/927/" rel="nofollow">https://xkcd.com/927/</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301790"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wtetzner" class="hnuser">wtetzner</a> <a href="https://news.ycombinator.com/item?id=47301790">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47295635" class="clicky" aria-hidden="true">parent</a> | <a href="#47294669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Can you explain how this is relevant here?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315699"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jstanley" class="hnuser">jstanley</a> <a href="https://news.ycombinator.com/item?id=47315699">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47301790" class="clicky" aria-hidden="true">parent</a> | <a href="#47294669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Adding a new feature to unify existing features is perfectly isomorphic to defining a new standard to unify existing standards.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318735"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wtetzner" class="hnuser">wtetzner</a> <a href="https://news.ycombinator.com/item?id=47318735">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47315699" class="clicky" aria-hidden="true">parent</a> | <a href="#47294669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's not though, unless the new feature and existing features continue to exist as disjoint things. If the new feature subsumes the old ones, then you've reduced the number of features in the language.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47327606"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jstanley" class="hnuser">jstanley</a> <a href="https://news.ycombinator.com/item?id=47327606">1 day ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47318735" class="clicky" aria-hidden="true">parent</a> | <a href="#47294669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The same is true of standards.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294669"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294669">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47294616" class="clicky" aria-hidden="true">prev</a> | <a href="#47295334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It doesn't have too many features, it arguably does not have enough. The issue is that the current features don't play nicely with each other, so much of the work has been in making sure they do, such as with async traits as an example: there is no reason why you can make a function async but not inside a trait, and this was the case until very recently.
<p>Beyond that, what the article shows is exactly what I want, I want as much type safety as possible especially for critical systems code which is increasingly what Rust is being used for.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47296398"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=SkiFire13" class="hnuser">SkiFire13</a> <a href="https://news.ycombinator.com/item?id=47296398">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294669" class="clicky" aria-hidden="true">parent</a> | <a href="#47294746" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Re: async in traits, the feature was delayed because it relied on the "Generic Associated Types" and "Impl Trait in Traits" features. If Rust delayed the whole `async` feature for working on those pretty type-theoretic features what would you have thought?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47297992"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47297992">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47296398" class="clicky" aria-hidden="true">parent</a> | <a href="#47294746" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well in practice the async_trait crate worked just fine. If Rust delayed the whole async feature I'd have thought they'd have better been able to handle the function coloring problem via something like OCaml's algebraic effects rather than following the trend of JS and C# back then, as OCaml's came along much later after more research into the model.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294746"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LiamPowell" class="hnuser">LiamPowell</a> <a href="https://news.ycombinator.com/item?id=47294746">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294669" class="clicky" aria-hidden="true">parent</a> | <a href="#47296398" class="clicky" aria-hidden="true">prev</a> | <a href="#47295334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This inevitably happens when the approach to language design is "try it and see". I know people here hate design-by-committee, but historically it's led to some very cohesive languages.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295799"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wolvesechoes" class="hnuser">wolvesechoes</a> <a href="https://news.ycombinator.com/item?id=47295799">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294746" class="clicky" aria-hidden="true">parent</a> | <a href="#47294769" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; design-by-committee
<p>I don't think it is about having committee, but rather having a spec. And I mean spec, not necessarily ISO standard. There should be a description of how specific features work, what is expected behavior, what is unexpected and should be treated as bug, and what is rationale behind specific decision.</p>
<p>Coincidentally people here hate specs as well, and that explains some things.</p>
<p>I know there is some work on Rust spec, but it doesn't seem to progress much.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301669"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bitwalker" class="hnuser">bitwalker</a> <a href="https://news.ycombinator.com/item?id=47301669">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47295799" class="clicky" aria-hidden="true">parent</a> | <a href="#47294769" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">AIUI, that is what the MIR formalization work is about, and it seems to be moving along fine. My impression is that covers essentially all the interesting parts of Rust worth specifying formally.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294769"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=metaltyphoon" class="hnuser">metaltyphoon</a> <a href="https://news.ycombinator.com/item?id=47294769">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294746" class="clicky" aria-hidden="true">parent</a> | <a href="#47295799" class="clicky" aria-hidden="true">prev</a> | <a href="#47295117" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; I know people here hate design-by-committee, but historically it's led to some very cohesive languages.
<p>C++ is not cohesive at all</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295243"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LiamPowell" class="hnuser">LiamPowell</a> <a href="https://news.ycombinator.com/item?id=47295243">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294769" class="clicky" aria-hidden="true">parent</a> | <a href="#47295117" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I didn't say this applies to every committee, but I do think the opposite applies to almost every "try it and see" language.
<p>Examples of cohesive languages designed by committees would be Ada and Haskell.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295426"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47295426">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47295243" class="clicky" aria-hidden="true">parent</a> | <a href="#47295117" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Haskell is anything but cohesive, depending on which feature flags are enabled on GHC, or any other compiler.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295117"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=scrubs" class="hnuser">scrubs</a> <a href="https://news.ycombinator.com/item?id=47295117">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294746" class="clicky" aria-hidden="true">parent</a> | <a href="#47294769" class="clicky" aria-hidden="true">prev</a> | <a href="#47295289" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well ok ... experiment but maybe unlike c++ we could have added N keywords removed M keywords for arguably net-simpler language.
<p>Geez I'd hate to be in rust dev shoes if I can't remove something later when I have a better better min/max. I guess this could be done off main, stable.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295289"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Starlevel004" class="hnuser">Starlevel004</a> <a href="https://news.ycombinator.com/item?id=47295289">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294746" class="clicky" aria-hidden="true">parent</a> | <a href="#47295117" class="clicky" aria-hidden="true">prev</a> | <a href="#47294767" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust is also design-by-committee.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294767"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294767">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294746" class="clicky" aria-hidden="true">parent</a> | <a href="#47295289" class="clicky" aria-hidden="true">prev</a> | <a href="#47295334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes, however how many of them are used in production to some level of scale (not even to the scale of Rust)? Stroustrup's quote and all that.
<p>Rust's development process is also design by committee, interestingly enough.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295256"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LiamPowell" class="hnuser">LiamPowell</a> <a href="https://news.ycombinator.com/item?id=47295256">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294767" class="clicky" aria-hidden="true">parent</a> | <a href="#47295334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Rust's development process is also design by committee, interestingly enough.
<p>Sure, but it's still quite informal and they just add things as they go instead of writing a complete standard and figuring out how everything interacts before anything is added to the language. Design-by-committee was probably not the best term to use.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295334"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=j-krieger" class="hnuser">j-krieger</a> <a href="https://news.ycombinator.com/item?id=47295334">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47294669" class="clicky" aria-hidden="true">prev</a> | <a href="#47294793" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">After working with Rust for half a decade I‘m afraid I have to agree. A lot of the newer features have weird edge cases with promises for fixes stuck in bikeshedding hell for years (looking at you const generics). Alternatively feature authors wait on dependecies that will never ship.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294793"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jcranmer" class="hnuser">jcranmer</a> <a href="https://news.ycombinator.com/item?id=47294793">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47295334" class="clicky" aria-hidden="true">prev</a> | <a href="#47294537" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You're not wrong here. Not that I'm entirely up-to-speed on all of the deep Rust discussions, but the sense I have of the language evolution is that while there is definitely a <em>loud</em> contingent of people pushing for a lot of the complexity of full effect systems or linear types, these sorts of proposals aren't actually all that likely to actually move forward in the language.
<p>(I should note that of all of the features mentioned in this blog post, the only one I actually expect to see in Rust someday is pattern types, and that's largely because it partially exists already in unstable form to use for things like NonZeroU32.)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294846"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294846">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294793" class="clicky" aria-hidden="true">parent</a> | <a href="#47295657" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yoshua works directly on developing the language, and mentions he is working on these features specifically (he is part of the effects initiative), I'm not sure you won't see these features in Rust.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300808"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Rusky" class="hnuser">Rusky</a> <a href="https://news.ycombinator.com/item?id=47300808">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294846" class="clicky" aria-hidden="true">parent</a> | <a href="#47295657" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yoshua is part of the "loud contingent" being described. He's not on the lang team, and he's been "working on" things like keyword generics for years without any indication that they are going to make it into the language.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47309794"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47309794">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47300808" class="clicky" aria-hidden="true">parent</a> | <a href="#47295657" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>We (Oli, Niko, and Yosh) are excited to announce the start of the Keyword Generics Initiative, a new initiative 1 under the purview of the language team</em>
<p><a href="https://blog.rust-lang.org/inside-rust/2022/07/27/keyword-generics/#fn-initiative" rel="nofollow">https://blog.rust-lang.org/inside-rust/2022/07/27/keyword-ge...</a></p>
<p>Maybe he's not on <em>the</em> language team (I haven't read enough into Rust governance structures to know definitively) but it's not like he's on some random person working on this. And yes, work takes time, I actually disagreed with his initial approach where his syntax was to have a bunch of effects before the function name, and everyone rightly mentioned how messy it was. So they should be taking it slow anyway.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316443"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Rusky" class="hnuser">Rusky</a> <a href="https://news.ycombinator.com/item?id=47316443">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47309794" class="clicky" aria-hidden="true">parent</a> | <a href="#47295657" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The thing is that anyone can show up and spend time discussing ideas in Rust project spaces. From the outside it is easy to confuse that with actual movement toward landing changes in the language.
<p>(The communication aspect of this is something that has bothered me many times in the past- even people who <em>are</em> lang team members often phrase things in a way that makes it sound like something is on its way in, when it's still just in the stage of "we're kinda noodling with ideas.")</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295657"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tcfhgj" class="hnuser">tcfhgj</a> <a href="https://news.ycombinator.com/item?id=47295657">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294793" class="clicky" aria-hidden="true">parent</a> | <a href="#47294846" class="clicky" aria-hidden="true">prev</a> | <a href="#47294537" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What complexity?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294537"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=fabiensanglard" class="hnuser">fabiensanglard</a> <a href="https://news.ycombinator.com/item?id=47294537">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47294793" class="clicky" aria-hidden="true">prev</a> | <a href="#47294585" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree that the complexity is getting scary. They keep on adding more and more stuff and it is hard to follow.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295665"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tcfhgj" class="hnuser">tcfhgj</a> <a href="https://news.ycombinator.com/item?id=47295665">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294537" class="clicky" aria-hidden="true">parent</a> | <a href="#47294585" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Could you expand a bit more?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294585"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=xiphias2" class="hnuser">xiphias2</a> <a href="https://news.ycombinator.com/item?id=47294585">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47294537" class="clicky" aria-hidden="true">prev</a> | <a href="#47300986" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The main problem I see is adding things slowly instead of automatic rewrites.
<p>I remember adding lifetimes in some structs and then wanted to use generics and self pointing with lifetimes because that made sense, and then it didn't work because the composition of some features was not yet part of Rust.</p>
<p>Another thing: there are annotations for lifetimes in function signatures, but not inside the functions where there is a lot of magic happening that makes understanding them and working with them really hard: after finally the borrow checking gave me errors, that's when I just started to getting lots of lifetime errors, which were not shown before.</p>
<p>Rust should add these features but take out the old ones with guaranteed automatic update path.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47294734"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47294734">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">root</a> | <a href="#47294585" class="clicky" aria-hidden="true">parent</a> | <a href="#47300986" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The edition mechanism covers your last paragraph.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300986"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=russdill" class="hnuser">russdill</a> <a href="https://news.ycombinator.com/item?id=47300986">3 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">parent</a> | <a href="#47294585" class="clicky" aria-hidden="true">prev</a> | <a href="#47305968" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think part of the idea is you and to make it impossible to misuse an underlying API. This can make development much less complex.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305968"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jeffreygoesto" class="hnuser">jeffreygoesto</a> <a href="https://news.ycombinator.com/item?id=47305968">2 days ago</a> | <a href="#47294466" class="clicky" aria-hidden="true">prev</a> | <a href="#47295738" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Especially borrowing parts of objects reminds me of <a href="https://vale.dev" rel="nofollow">https://vale.dev</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47295738"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zamalek" class="hnuser">zamalek</a> <a href="https://news.ycombinator.com/item?id=47295738">3 days ago</a> | <a href="#47305968" class="clicky" aria-hidden="true">prev</a> | <a href="#47305345" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm terrified by the notion of try fns. Are we getting exceptions (and therefore losing one of rust's greatest features)?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47300886"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Pedro_Ribeiro" class="hnuser">Pedro_Ribeiro</a> <a href="https://news.ycombinator.com/item?id=47300886">3 days ago</a> | <a href="#47295738" class="clicky" aria-hidden="true">parent</a> | <a href="#47305345" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Isn't his point exactly that we don't want to have too many function colors and instead want a generic way of declaring side effects so people can do what they want (be it try fns, IO, async, etc..., no panicking)?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310387"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zamalek" class="hnuser">zamalek</a> <a href="https://news.ycombinator.com/item?id=47310387">2 days ago</a> | <a href="#47295738" class="clicky" aria-hidden="true">root</a> | <a href="#47300886" class="clicky" aria-hidden="true">parent</a> | <a href="#47305345" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">From the article:
<p>&gt; And on nightly it also has support for try fn and gen fn.</p>
<p>I haven't been able to figure out what a try fn is.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305345"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=semiinfinitely" class="hnuser">semiinfinitely</a> <a href="https://news.ycombinator.com/item?id=47305345">3 days ago</a> | <a href="#47295738" class="clicky" aria-hidden="true">prev</a> | <a href="#47305323" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">the most exciting thing about rust is that AI agents are good at writing it because its so highly structured</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305323"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=shevy-java" class="hnuser">shevy-java</a> <a href="https://news.ycombinator.com/item?id=47305323">3 days ago</a> | <a href="#47305345" class="clicky" aria-hidden="true">prev</a> | <a href="#47301198" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rustee devs are strange. It feels as if they are on a mission. I don't fully understand it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47301198"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=phplovesong" class="hnuser">phplovesong</a> <a href="https://news.ycombinator.com/item?id=47301198">3 days ago</a> | <a href="#47305323" class="clicky" aria-hidden="true">prev</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">async rust is the worse async out there. I prayed that rust did not include a async at all. But the JS devs pushed it thru. That pretty much sealed my rust use. Im still salty.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302222"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonask" class="hnuser">simonask</a> <a href="https://news.ycombinator.com/item?id=47302222">3 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">parent</a> | <a href="#47306989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You know what, I’ve heard people say this and thought “OK, maybe these other languages with GCs and huge runtimes really do something magical to make async a breeze”.
<p>But then I actually tried both TypeScript and C#, and no. Writing correct async code in those languages is not any nicer at all. What the heck is “.ConfigureAwait(false)”? How fun do you really think debugging promise resolution is? Is it even possible to contain heap/GC pressure when every `await` allocates?</p>
<p>Phooey. Rust async is doing just fine.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306108"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=usrnm" class="hnuser">usrnm</a> <a href="https://news.ycombinator.com/item?id=47306108">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47302222" class="clicky" aria-hidden="true">parent</a> | <a href="#47306307" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Try golang, where they did the only sane thing: everything is async from the very beginning, no function colouring</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306885"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonask" class="hnuser">simonask</a> <a href="https://news.ycombinator.com/item?id=47306885">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47306108" class="clicky" aria-hidden="true">parent</a> | <a href="#47306307" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think practical experience with Go reveals that this choice being “the only sane thing” is highly debatable. It comes with huge drawbacks.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307759"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=usrnm" class="hnuser">usrnm</a> <a href="https://news.ycombinator.com/item?id=47307759">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47306885" class="clicky" aria-hidden="true">parent</a> | <a href="#47306307" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Of course it has drawbacks, everything does, but my practical experience has been hugely in favor of what golang is doing, at least, in terms of cognitive load and code simplicity. It is very much worth it in many, many cases</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306307"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mrsmrtss" class="hnuser">mrsmrtss</a> <a href="https://news.ycombinator.com/item?id=47306307">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47302222" class="clicky" aria-hidden="true">parent</a> | <a href="#47306108" class="clicky" aria-hidden="true">prev</a> | <a href="#47307000" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In .NET 11 C# async management moved to the runtime, mostly eliminating heap allocations and also bringing clean stack traces. You really only need to think about ConfigureAwait(false) when building shared libraries or dealing with UI frameworks (even there you mostly don't need it).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306877"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonask" class="hnuser">simonask</a> <a href="https://news.ycombinator.com/item?id=47306877">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47306307" class="clicky" aria-hidden="true">parent</a> | <a href="#47307000" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You speak in the past tense, but .NET 11 is not released yet at time of writing. Runtime-async is not the current reality.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307538"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mrsmrtss" class="hnuser">mrsmrtss</a> <a href="https://news.ycombinator.com/item?id=47307538">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47306877" class="clicky" aria-hidden="true">parent</a> | <a href="#47307000" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">True, it's in preview currently, but actually .NET is already very efficient with async today also - <a href="https://hez2010.github.io/async-runtimes-benchmarks-2024/" rel="nofollow">https://hez2010.github.io/async-runtimes-benchmarks-2024/</a> (.NET9 tested here).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313375"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonask" class="hnuser">simonask</a> <a href="https://news.ycombinator.com/item?id=47313375">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47307538" class="clicky" aria-hidden="true">parent</a> | <a href="#47307000" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sure, it’s really fine for what it does, but it is not significantly easier to deal with than Rust async, and remains fundamentally unsuited in several scenarios where Rust async works really well.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307000"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47307000">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47302222" class="clicky" aria-hidden="true">parent</a> | <a href="#47306307" class="clicky" aria-hidden="true">prev</a> | <a href="#47302376" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Unless you are writing GUI code, ConfigureAwait() shouldn't be on your source code.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302376"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palata" class="hnuser">palata</a> <a href="https://news.ycombinator.com/item?id=47302376">3 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47302222" class="clicky" aria-hidden="true">parent</a> | <a href="#47307000" class="clicky" aria-hidden="true">prev</a> | <a href="#47306989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">How does it compare to Kotlin async? I find Kotlin generally hits a good balance across the board.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306989"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306989">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">parent</a> | <a href="#47302222" class="clicky" aria-hidden="true">prev</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not sure who pushed async Rust, but at least async JS does work without having to hunt down for runtimes, and naturally the answer is always Tokio.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311115"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47311115">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47306989" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Usually the answer is embassy for me.
<p>And embedded systems vastly outnumber classical computers. Every classical computer includes several microcontrollers, every car, modern appliance, camera, toy, etc does too. Safe languages for embedded and OSes is very important. Rust just happens to be pretty good for other use cases too, which is a nice bonus. But that means the language can't be tied to a single prescribed runtime. And that it can't have a GC, etc.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311607"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47311607">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47311115" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">PTC and Aicas would disagree there.
<p>As might microEJ, Meadows, F-Secure, Astrobe and a few others.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311710"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47311710">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47311607" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; PTC and Aicas would disagree there.
<p>Never heard of either. You will have to expand on your reasoning. Microcontrollers do outnumber classical computers though, that is just a fact. So i don't see why there is anything to disagree about there. Even GPUs have helper microcontrollers for thermal management and other functions.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312093"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47312093">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47311710" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">They have been selling real time bare metal Java runtimes for embedded systems, widely deployed across weapon systems in battleships and missile tracking units, factory automation, satellites, and other similar systems for the last decades.
<p>I bet many of those helper microcontrollers, are still Assembly, compiler specific C, and if there is Rust support, most likely only no_std fits, thus no async anyway.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312633"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47312633">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47312093" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Java on smartcard etc is a thing. I haven't met anyone who used that and actually like it. And it is apparently nothing like normal java.
<p>Many microcontrollers are indeed still running C, but things are starting to change. Esperif has official support for Rust for example, and other vendors are experimenting with that too. Many other microcontrollers have good community support.</p>
<p>&gt; if there is Rust support, most likely only no_std fits, thus no async anyway.</p>
<p>This is just plain incorrect. The beauty of async in rust is that it does work on no_std. You don't need an allocator even to use Embassy. Instead becuause async tasks are perfectly sized, you can reserve space statically at compile time, you just need to specify with an attribute how many concurrent instances of a given task should be supported.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314561"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47314561">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47312633" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">PTC and Aicas aren't Java on smartcards, they are Java on high integrity computing where human lives might be at stake.
<p>Interesting how compiler specific extensions are ok for C, with a freestanding subset, or Rust no_std, but when it goes to other languages it is no longer the same.</p>
<p>I stand corrected on async Rust then.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315734"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47315734">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47314561" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Interesting how compiler specific extensions are ok for C, with a freestanding subset, or Rust no_std, but when it goes to other languages it is no longer the same.
<p>Not sure what you mean here. For Rust there is only one de facto compiler currently, though work is ongoing on gccrs (not to be confused with rustc_codegen_gcc, which only replaces the llvm backend but keeps the rest of the compiler the same). Work is also ongoing on an official spec. But as it currently stands there are no compiler specific extensions.</p>
<p>If you meant the attribute I mentioned for embassy? That is just processed by a rust proc-macro, similar to derives with serde is used to generate (de)serialisation code. It too adds custom attributes on members.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319904"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47319904">1 day ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47315734" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It means that being constrained to C compiler dialect for tiny CPUs instead of ISO C proper, or being constrained to [no_std] instead of the whole Rust capabilities and ecosystem, isn't seen under the same light as when it is C++, Swift, Go, Java or whatever else might also be constrained for the same purpose.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322371"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="400" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47322371">1 day ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">root</a> | <a href="#47319904" class="clicky" aria-hidden="true">parent</a> | <a href="#47308327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Hm, I haven't come across such sentiment. It is fairly well understood that if you use C++ for example on embedded, you are limited as to what features you can use. I remember coming across that when using PlatformIO for Arduino many years ago, certain parts of STL was just missing.
<p>The other languages you mentioned I have no personal experience of in embedded (and hardly outside embedded either), but I understand they are less common (apart from Java possibly, but only in certain niches). There is also Ada/SPARK and MicroPython (which always seemed more like an educational thing for people new to programming). I haven't used either.</p>
<p>I would like to add that it feels like no-std rust is less constrained than freestanding C to me. I haven't managed to figure out why exactly. Perhaps the ecosystem of crates in Rust for embedded is just better, with many crates offering a way to opt out of the std-parts (plus a number of good libraries aimed directly at no-std). Perhaps it is that it is easy to add alloc to no-std if you are working on a higher end embedded system (with obvious tradeoffs in code size, memory usage etc). Or perhaps the no-std parts of rust simply contains more than freestanding C.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47308327"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=poppafuze" class="hnuser">poppafuze</a> <a href="https://news.ycombinator.com/item?id=47308327">2 days ago</a> | <a href="#47301198" class="clicky" aria-hidden="true">prev</a> | <a href="#47310972" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">"Because though we’re not doing too bad, we’re no Ada/SPARK yet" ... props to the king. A worthy aspiration. Classy.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47310972"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eviks" class="hnuser">eviks</a> <a href="https://news.ycombinator.com/item?id=47310972">2 days ago</a> | <a href="#47308327" class="clicky" aria-hidden="true">prev</a> | <a href="#47302546" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Cool features, what are the chances that's going to happen in the next decade?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302546"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=plantain" class="hnuser">plantain</a> <a href="https://news.ycombinator.com/item?id=47302546">3 days ago</a> | <a href="#47310972" class="clicky" aria-hidden="true">prev</a> | <a href="#47302423" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I used to hate Golang for not having generics and how verbose getting basic things done was. Then I read posts like this and realise, my god, Rob Pike was so, so right.
<p>Do these people ever ship anything? Or is it just endless rearranging of deckchairs?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302747"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=beanjuiceII" class="hnuser">beanjuiceII</a> <a href="https://news.ycombinator.com/item?id=47302747">3 days ago</a> | <a href="#47302546" class="clicky" aria-hidden="true">parent</a> | <a href="#47306978" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I already need a reference to read rust code, looks like I'll need a third reference sheet. The language is currently bordering on spaghetti</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306943"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ozgrakkurt" class="hnuser">ozgrakkurt</a> <a href="https://news.ycombinator.com/item?id=47306943">2 days ago</a> | <a href="#47302546" class="clicky" aria-hidden="true">root</a> | <a href="#47302747" class="clicky" aria-hidden="true">parent</a> | <a href="#47306978" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">The most annoying part is that you can't just go to source code or docs and understand some code. I still can't do it after spending many years using it. You have to wade through 7 layers of macros and traits to understand some basic thing most of the time.
<p>It is easier to understand musl-libc code compared to understanding a http library in rust which is just insane to me.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306978"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47306978">2 days ago</a> | <a href="#47302546" class="clicky" aria-hidden="true">parent</a> | <a href="#47302747" class="clicky" aria-hidden="true">prev</a> | <a href="#47302423" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I mostly agree, however it wouldn't harm Go, even to get back some of the niceties of Limbo that it still misses.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47302776"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=conorbergin" class="hnuser">conorbergin</a> <a href="https://news.ycombinator.com/item?id=47302776">3 days ago</a> | <a href="#47302423" class="clicky" aria-hidden="true">prev</a> | <a href="#47306904" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c88">Thank God for Zig</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47307006"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pjmlp" class="hnuser">pjmlp</a> <a href="https://news.ycombinator.com/item?id=47307006">2 days ago</a> | <a href="#47302776" class="clicky" aria-hidden="true">parent</a> | <a href="#47303226" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">For bringing us back to Modula-2?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47303226"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=esafak" class="hnuser">esafak</a> <a href="https://news.ycombinator.com/item?id=47303226">3 days ago</a> | <a href="#47302776" class="clicky" aria-hidden="true">parent</a> | <a href="#47307006" class="clicky" aria-hidden="true">prev</a> | <a href="#47306904" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Elaborate.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47305019"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=conorbergin" class="hnuser">conorbergin</a> <a href="https://news.ycombinator.com/item?id=47305019">3 days ago</a> | <a href="#47302776" class="clicky" aria-hidden="true">root</a> | <a href="#47303226" class="clicky" aria-hidden="true">parent</a> | <a href="#47306904" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don’t think PL theory driven design produces good systems languages.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306760"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47306760">2 days ago</a> | <a href="#47302776" class="clicky" aria-hidden="true">root</a> | <a href="#47305019" class="clicky" aria-hidden="true">parent</a> | <a href="#47306904" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Rust as it exists today is very much "PL theory" driven. It's not necessarily a good language, but it's been consistently ranked as the #1 "most loved" by Stack Overflow for the past few years.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47306904"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dzogchen" class="hnuser">dzogchen</a> <a href="https://news.ycombinator.com/item?id=47306904">2 days ago</a> | <a href="#47302776" class="clicky" aria-hidden="true">prev</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">The only thing Rust needs to have a chance to succeed is better C++ interoperability. Everything else is a nice to have.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr></table>]]></description>
      <link>https://news.ycombinator.com/item?id=47256376</link>
      <guid>https://news.ycombinator.com/item?id=47256376</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Anthropic is launching a new think tank amid Pentagon blacklist fight | The Verge]]></title>
      <description><![CDATA[<div class="duet--article--lede duet--page-layout--feature-article duet--ledes--feature-lede nebk4w0 nebk4w1">
<div class="_1ymtmqp7 nebk4w2 _1ymtmqp3">
<div class="nebk4w3 _1ymtmqpp">
<div class="_1p1nf4x0 _1p1nf4x1">
<div class="">
<p class="duet--article--dangerously-set-cms-markup _8enl99i _8enl99g _1xwtictc _1xwtict1">Co-founder Jack Clark, who will lead the new Anthropic Institute, said he had “no concerns” about research funding.</p>
</div>
</div>
<div class="_13g9mks2 _13g9mks0">
<div class="_13g9mks9">
<time datetime="2026-03-11T09:45:00+00:00">Mar 11, 2026, 9:45 AM UTC</time></div>
</div>
</div>
<div class="bu4cqq0">
<div class="nebk4w5 bu4cqq1 _1ibjt4j0 duet--layout--entry-image _1b9pgly0 _1b9pgly1 _1b9pgly2">
<div class="_1ymtmqpn _1ymtmqpw"><img alt="STK485_STK414_AI_SAFETY_B" data-chromatic="ignore" data-nimg="fill" class="x271pn0 c5" sizes="(max-width: 768px) 100vw, 700px" srcset="https://platform.theverge.com/wp-content/uploads/sites/2/2025/06/STK485_STK414_AI_SAFETY_B.jpg" src="https://platform.theverge.com/wp-content/uploads/sites/2/2025/06/STK485_STK414_AI_SAFETY_B.jpg" /></div>
</div>
<div class="nebk4w7 duet--media--caption qama0i0"><cite class="duet--article--dangerously-set-cms-markup _1xwtict2 qama0i5">Image: Cath Virginia / The Verge, Getty Images</cite></div>
</div>
<div class="nebk4w3 _1ymtmqpq">
<div class="_1p1nf4x0 _1p1nf4x1">
<div class="">
<p class="duet--article--dangerously-set-cms-markup _8enl99i _8enl99g _1xwtictc _1xwtict1">Co-founder Jack Clark, who will lead the new Anthropic Institute, said he had “no concerns” about research funding.</p>
</div>
</div>
<div class="_13g9mks2 _13g9mks0">
<div class="_13g9mks9">
<time datetime="2026-03-11T09:45:00+00:00">Mar 11, 2026, 9:45 AM UTC</time></div>
</div>
</div>
</div>
</div><div class="duet--layout--entry-body-container _1t5ltw90 _1ymtmqp3 _1ymtmqp15 _1t5ltw91">
<div class="duet--layout--entry-body _9f4de40">
<div class="_1ymtmqp11">
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Amid a <a href="https://www.theverge.com/ai-artificial-intelligence/883456/anthropic-pentagon-department-of-defense-negotiations">weekslong</a> <a href="https://www.theverge.com/ai-artificial-intelligence/885963/anthropic-dod-pentagon-tech-workers-ai-labs-react">conflict</a> <a href="https://www.theverge.com/ai-artificial-intelligence/887309/openai-anthropic-dod-military-pentagon-contract-sam-altman-hegseth">with</a> the Pentagon, resulting in a <a href="https://www.theverge.com/ai-artificial-intelligence/890347/pentagon-anthropic-supply-chain-risk">blacklist</a> and a <a href="https://www.theverge.com/ai-artificial-intelligence/891377/anthropic-dod-lawsuit">lawsuit</a>, Anthropic is shaking up its C-suite and research initiatives. The company announced Wednesday that it’s launching a new internal think tank, called the Anthropic Institute, that combines three of Anthropic’s current research teams. It will focus on researching AI’s large-scale implications, such as “what happens to jobs and economies, whether AI makes us safer or introduces new dangers, how its values might shape ours, and whether we can retain control,” per the company.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">The news comes with C-suite changes, too. Anthropic cofounder Jack Clark is moving into a new role leading the think tank. His new title will be head of public benefit, after more than five years as head of public policy. The public policy team — which tripled in size in 2025, per Anthropic — will now be led by Sarah Heck, who was formerly head of external affairs. Anthropic will also open its planned office in Washington, DC, and the public policy team will continue to focus on issues like national security, AI infrastructure, energy, and “democratic leadership in AI.”</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Clark told <em>The Verge</em> that the Anthropic Institute’s debut has been in the works for a while, and that he’s been thinking about moving into a role like this since November. But the timing comes just days after Anthropic sued the US government over its designation as a supply-chain risk, which would bar its clients from using Anthropic’s tech at all in their own work with the Department of Defense. The suit alleges that the Trump administration illegally blacklisted the company for setting “red lines” on mass domestic surveillance and fully autonomous lethal weapons.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">When asked about it, Clark said, “It’s never dull working in AI here at Anthropic — there’s always something going on … The pace of AI progress isn’t slowing itself down for external events, and neither are we.” Clark said the situation hasn’t “directly changed” the planned research agenda but that he felt it “has affirmed” Anthropic’s decision to release more information to the public. “What we’re experiencing with the last few weeks just sort of shows you how much hunger there is for a larger national conversation by the public about this technology,” he said.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">The Anthropic Institute launches with about 30 people, including founding members Matt Botvinick, formerly of Google DeepMind; Anton Korinek, a professor on leave from the University of Virginia’s department of economics; and Zoe Hitzig, a researcher <a href="https://www.nytimes.com/2026/02/11/opinion/openai-ads-chatgpt.html">who left OpenAI</a> after its decision to introduce ads within ChatGPT. The new think tank combines Anthropic’s <a href="https://www.theverge.com/ai-artificial-intelligence/836335/anthropic-societal-impacts-team-ai-claude-effects">societal impacts team</a>, which studies AI’s impacts on different areas of society; its frontier red team, which stress-tests AI systems for vulnerabilities and issues; and its economic research team, which tracks AI’s implications for the economy and the labor market. The Anthropic Institute also plans to “incubate” new teams, such as a team led by Botvinick studying how AI will impact the legal system. Hitzig and Korinek will lead large economic research projects. Clark said he expects the think tank’s number of staff will double every year for the foreseeable future.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">This year in particular, there’s an increasing amount of pressure on high-valuation AI companies like Anthropic, which <a href="https://www.reuters.com/business/retail-consumer/anthropic-plans-an-ipo-early-2026-ft-reports-2025-12-03/">reportedly</a> plans to IPO this year. Anthropic’s <a href="https://www.documentcloud.org/documents/27781298-anthropic-v-dow/">court</a> <a href="https://storage.courtlistener.com/recap/gov.uscourts.cand.465515/gov.uscourts.cand.465515.6.5.pdf">filings</a> revealed that the company generated more than $5 billion in all-time commercial revenue and that it has spent $10 billion to date on model training and inference. It also said that the company has “received outreach from numerous outside partners … expressing confusion about what was required of them and concern about their ability to continue to work with Anthropic” and that “dozens of companies have contacted Anthropic” seeking guidance and “in some cases, an understanding of their termination rights.” Anthropic said that depending on the interpretation of what the government will prohibit, exactly, “hundreds of millions of 2026 revenue is at risk” at least, and in the most severe case, it would be multiple billions.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Is Anthropic concerned about devoting more resources to long-term research when it’s very likely to lose some portion of its income in the short term? When <em>The Verge</em> asked Clark, he said he had “no concerns.”</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">“People tend to buy trust,” Clark said. “A lot of what we can produce are the sorts of research that help businesses trust us … Long-term, Anthropic has always viewed its investment in safety — and studying and reporting on the safety of its systems — as being not a cost center but a profit center.”</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Clark also said he believes that powerful AI (essentially <a href="https://www.theverge.com/ai-artificial-intelligence/845890/ai-companies-rebrand-agi-artificial-general-intelligence">Anthropic’s own term for AGI</a>, or artificial general intelligence) will arrive by the end of this year or early 2027, and that he decided to change roles largely due to the “pace of AI progress.” He added that when he looked back at his work last year, he focused more on policy matters, like <a href="https://www.theverge.com/ai-artificial-intelligence/787918/sb-53-the-landmark-ai-transparency-bill-is-now-law-in-california">SB 53</a>, than he did AI R&amp;D and other matters he wanted to give attention to. Anthropic said in a release that the Anthropic Institute is specifically dedicated to answering the “hardest questions posed by powerful AI.”</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Of course, as <em>The Verge</em> wrote <a href="https://www.theverge.com/ai-artificial-intelligence/836335/anthropic-societal-impacts-team-ai-claude-effects">in December</a>, a lot of tech companies are pro-transparency until it’s bad for business. So what happens if and when the Anthropic Institute’s research teams uncover results that make the company look bad?</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Clark said that Anthropic’s cofounders have “similar values” about the importance of public disclosure, especially since the company is technically a public benefit corporation, meaning it has the ability to carry out objectives “not solely for fiduciary gain.” He added that in a conversation he had with CEO Dario Amodei last week, they aligned on the importance of transparency despite PR challenges that could come from it.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">But the Anthropic Institute’s research could require significant compute at a time when companies are racing to <a href="https://www.cnbc.com/2025/05/14/meta-google-openai-artificial-intelligence-safety.html">prioritize commercial products</a>. Clark said outside the resources dedicated to frontier model pre-training, Anthropic allocates its compute on a week-by-week basis according to “what seems most important,” so no precise portion has been set aside, but he doesn’t anticipate there being any conflicts.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">The Anthropic Institute also plans to study people’s emotional dependence on AI, an intensifying problem that’s <a href="https://www.theverge.com/podcast/779974/chatgpt-chatbots-ai-psychosis-mental-health">gained public awareness</a> over the past year. Clark said that so far, Anthropic’s research teams have studied types of conversations happening with Claude and measured the tech’s ability to persuade people of things or act sycophantic, but they haven’t spent as much time talking to people using the technology about their individual experiences. He said the think tank plans to conduct large-scale social science research, including using Anthropic’s AI to <a href="https://www.theverge.com/ai-artificial-intelligence/838243/anthropic-will-start-using-ai-to-interview-its-users-about-their-experience-with-ai">conduct interviews with users</a>.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">“I think of this as: Social media had a huge effect on society, and it wasn’t just based on what was happening on the social media platforms. It was, ‘How was the use of social media changing people?’” Clark said. “We want to understand, ‘How does the use of AI change people?’”</p>
</div>
</div>
</div>
<div class="duet--layout--rail _1xql9yl0 _1xql9yl1">
<div class="_1xql9yl2 _1xql9yl6 _1xql9yl8">
<form class="a18g6g0 _1ymtmqpz _1ymtmqpj a18g6g5" action="action">
<div class="duet--cta--newsletter a18g6g9">
<div class="a18g6gd">
<h2 class="a18g6gh">The Verge Daily</h2>
<p class="a18g6gi">A free daily digest of the news that matters most.</p>
</div>
<div class="a18g6gy a18g6gz">
<fieldset><div class="a18g6g12 a18g6g11">
<div class="a18g6g16 a18g6g1e duet--cta--form-field-text _1i902bu0"><label for="email" class="_1pbfapu0 _1yjvsxi0">Email (required)</label>
</div>
</div>
</fieldset><div class="a18g6g1q a18g6gj">By submitting your email, you agree to our <a href="https://www.voxmedia.com/legal/terms-of-use" class="a18g6g1p">Terms</a> and <a href="https://www.voxmedia.com/legal/privacy-notice" class="a18g6g1p">Privacy Notice</a>. This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy" class="a18g6g1p">Privacy Policy</a> and <a href="https://policies.google.com/terms" class="a18g6g1p">Terms of Service</a> apply.</div>
</div>
</div>
</form>
</div>
</div>
</div>]]></description>
      <link>https://www.theverge.com/ai-artificial-intelligence/892478/anthropic-institute-think-tank-claude-pentagon-jack-clark</link>
      <guid>https://www.theverge.com/ai-artificial-intelligence/892478/anthropic-institute-think-tank-claude-pentagon-jack-clark</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How to Audit a Rails Codebase: Legacy App Playbook]]></title>
      <description><![CDATA[<header>
<p>My legacy Rails app playbook. After 50+ engagements, here's the exact process, tools, and stakeholder questions I use in week one.</p>
<small>Ally Piechowski · <time datetime="2026-03-05">Mar 5, 2026</time> · 12 min read</small>
<ul role="list"><li><a href="https://piechowski.io/tags/rails">rails</a></li>
<li><a href="https://piechowski.io/tags/ruby">ruby</a></li>
<li><a href="https://piechowski.io/tags/legacy">legacy</a></li>
<li><a href="https://piechowski.io/tags/career">career</a></li>
<li><a href="https://piechowski.io/tags/security">security</a></li>
<li><a href="https://piechowski.io/tags/activerecord">activerecord</a></li>
<li><a href="https://piechowski.io/tags/development">development</a></li>
</ul></header><img src="https://piechowski.io/post/how-i-audit-a-legacy-rails-codebase/bundle-audit_hubdfe0f1032e5e0f6888e3c8791c14ae7_147924_1500x0_resize_q75_h2_box_2.webp" alt="How I Audit a Legacy Rails Codebase in the First Week" width="1500" height="1062" /><p>After 50+ engagements, I’ve learned that the first week isn’t about reading the code. It’s about reading the signals.</p><p>The client already has opinions about what’s wrong. They’re usually partially right and almost always wrong about <em>why</em>. Your job in week one is to separate what looks bad from what’s actually dangerous.</p>
<p><strong>TL;DR:</strong> Start with a stakeholder interview — not the code. Then read three files (Gemfile, schema.rb, routes.rb) before running a single tool. Run security scans first. Use SimpleCov zero-coverage files as your “fear map.” Deliver a single-page triage, not an exhaustive report.</p>
<hr /><p><strong>Table of Contents</strong></p>
<ul><li><a href="#before-you-clone-the-repo-the-stakeholder-interview">Before You Clone the Repo: The Stakeholder Interview</a></li>
<li><a href="#step-1-analyzing-the-gemfile-schema-and-routes-for-technical-debt">Step 1: Analyzing the Gemfile, Schema, and Routes for Technical Debt</a></li>
<li><a href="#the-best-tools-for-a-rails-codebase-audit">The Best Tools for a Rails Codebase Audit</a></li>
<li><a href="#when-a-rails-app-needs-a-rewrite-vs-a-refactor">When a Rails App Needs a Rewrite vs. a Refactor</a></li>
<li><a href="#what-a-rails-audit-should-deliver-the-week-one-report">What a Rails Audit Should Deliver: The Week One Report</a></li>
<li><a href="#quick-reference-command-sequence">Quick-Reference Command Sequence</a></li>
<li><a href="#faq">FAQ</a></li>
</ul><hr /><p>The client bashfully frames everything as “technical debt”, but the codebase actually seems a bit healthy at face value. The test suite runs, even if it’s a bit slow. Deploys happen automatically and regularly, even if they sometimes need a babysitter. But the real issue is that the engineer that gave notice last month wrote the entire checkout flow. They never documented it, and now the team is terrified to contribute to the flow. It’s good code, but it’s complex and under documented. The lack of knowledge sharing is the real problem, not the code itself.</p>
<h2 id="before-you-clone-the-repo-the-stakeholder-interview">Before You Clone the Repo: The Stakeholder Interview</h2>
<p>The most diagnostic tool you have isn’t a gem.</p>
<p>You ask when the last time they deployed on a Friday was. They laugh. That laugh tells you more than any code metric could show you. It shows you that deploys are high stakes and that the team is living in fear of breaking production. On further investigation, you learn that there is no safe rollback procedure for deployment. If a deploy goes wrong, the team has to scramble to fix it in production. The server goes down, the team has to manually fix it. This is something static analysis won’t show you, but it’s also a critical signal of the codebase’s health.</p>
<p><strong>Questions for developers:</strong></p>
<ul><li>“What’s the one area you’re afraid to touch?”</li>
<li>“When’s the last time you deployed on a Friday?”</li>
<li>“What broke in production in the last 90 days that wasn’t caught by tests?”</li>
</ul><p><strong>Questions for the CTO/EM:</strong></p>
<ul><li>“What feature has been blocked for over a year?”</li>
<li>“Do you have real-time error visibility right now?”</li>
<li>“What was the last feature that took significantly longer than estimated?”</li>
</ul><p><strong>Questions for business stakeholders:</strong></p>
<ul><li>“Are there features that got quietly turned off and never came back?”</li>
<li>“Are there things you’ve stopped promising customers?”</li>
</ul><p>Deploy frequency is a proxy for codebase health — teams with fragile apps stop shipping.</p>
<hr /><h2 id="step-1-analyzing-the-gemfile-schema-and-routes-for-technical-debt">Step 1: Analyzing the Gemfile, Schema, and Routes for Technical Debt</h2>
<p>You can form a working thesis in 30 minutes without running a single tool.</p>
<p>The <code>transactions</code> table had 122 columns. That number alone is a signal, but it starts to make a grim kind of sense when you see what’s in there. <code>stripe_charge_id</code>, <code>wire_transfer_reference</code>, <code>ach_routing_number</code>, <code>paypal_transaction_id</code> — every payment processor the company had ever integrated with, each with their own set of nullable columns, all crammed into one table. A wire transfer doesn’t need a <code>stripe_charge_id</code>. A Stripe charge doesn’t need an <code>ach_routing_number</code>. Most rows are mostly null.</p>
<p>The separation of concerns problem is bad, but fixable. The integer primary key is not. The table had been around since the company’s founding. They processed a healthy volume of transactions every day. I didn’t need to run a query to know they were probably sitting somewhere north of a billion rows. The maximum for a signed integer is about 2.1 billion. Nobody had thought about it because the app had always worked. I asked the CTO when they expected to hit that limit. He had no idea the limit existed.</p>
<p><strong><code>Gemfile</code></strong> — count the gems, look for duplicated responsibilities (two auth systems, two file upload gems), note anything you can’t explain.</p>
<p><strong><code>db/schema.rb</code></strong> — god tables with 30+ columns, missing indexes on obvious foreign key columns, dead tables with no model counterpart, <code>integer</code> primary keys in an old high-volume app (a quiet ID exhaustion timebomb).</p>
<p><strong><code>config/routes.rb</code></strong> — total count and ratio of RESTful resources to custom one-off routes. 500 custom routes isn’t a style problem — it’s an architecture one.</p>
<hr /><h2 id="the-best-tools-for-a-rails-codebase-audit">The Best Tools for a Rails Codebase Audit</h2>
<p>SimpleCov reports 81% coverage. Looks pretty healthy, right? Well when you take a closer look, you notice a few files have zero coverage: <code>order.rb</code>, <code>payment.rb</code>, and <code>subscription.rb</code>. These 3 models, that touch money, have never been tested. At all! The 81% was carried by hundreds of tests on utilities, views, mailers, and controllers.</p>
<h3 id="security--run-first-non-negotiable">Security — Run First, Non-Negotiable</h3>
<div class="highlight"><pre class="language-bash" data-lang="bash">bundle audit check --update
bundle exec brakeman --format html -o brakeman_report.html
</pre></div>
<p>Severity matters more than count. One critical CVE in an auth gem is a different problem than 20 low-severity advisories. With Brakeman, focus on confidence level and whether warnings are in high-traffic code paths.</p>
<h3 id="dependency-health">Dependency Health</h3>
<div class="highlight"><pre class="language-bash" data-lang="bash">bundle outdated
bundle exec bundle_report compatibility --rails-version=7.2  # via next_rails gem
</pre></div>
<p>Name the EOL date. Rails 6.1 went EOL June 2024. In regulated industries, running an EOL version isn’t just tech debt — it’s a compliance liability.</p>
<h3 id="sloc-and-complexity">SLOC and Complexity</h3>
<p>Honestly, <code>cloc</code> is mostly a gut check. I’m not looking for a specific number — I’m looking at where the lines are. If 80% of the codebase lives in <code>app/models</code>, that tells me something. Models doing all the heavy lifting usually means business logic tightly coupled to ActiveRecord, which makes it hard to test in isolation and even harder to change safely. High test coverage numbers don’t fix that — you can have 80% coverage and still have every important decision buried in a callback on a 900-line model.</p>
<p>On the other hand, if I see a healthy <code>app/services</code> or a lot of plain Ruby objects scattered around, that’s a good sign. It means someone at some point made a deliberate choice to pull logic out of the models. The code isn’t necessarily cleaner, but the instinct was right.</p>
<div class="highlight"><pre class="language-bash" data-lang="bash">cloc app/
bundle exec rubycritic app/
</pre></div>
<p>Raw SLOC sets the scale of what you’re dealing with. RubyCritic’s churn-vs-complexity visualization is where it gets useful: files in the upper-right quadrant (high churn, high complexity) are actively hurting the team every sprint.</p>
<h3 id="model-structure">Model Structure</h3>
<p>This is the pass I always do manually, not just with tools. Walk the models directory deliberately: what are the god models, where are the callbacks concentrated, what does the association graph look like?</p>
<div class="highlight"><pre class="language-bash" data-lang="bash"># active_record_doctor — run the full suite
bundle exec rails active_record_doctor:run
</pre></div>
<p>What to look for: missing unique indexes (race condition risk), wrong <code>dependent:</code> options (silent data corruption risk), <code>integer</code> PKs in old apps, and <a href="https://piechowski.io/post/why-is-default-scope-bad-rails/">dangerous <code>default_scope</code> usage</a> that quietly filters queries application-wide.</p>
<p>Then enable Bullet in development and browse the app. Count the N+1s on core pages.</p>
<h3 id="test-suite">Test Suite</h3>
<div class="highlight"><pre class="language-bash" data-lang="bash">time bundle exec rspec
COVERAGE=true bundle exec rspec  # with simplecov configured
</pre></div>
<p>Over 30 minutes is a crisis — developers won’t run it locally, which breaks the feedback loop entirely. <strong>Key takeaway: SimpleCov zero-coverage files are your fear map.</strong> Commented-out tests are the most honest signal in the codebase.</p>
<h3 id="ai-as-a-force-multiplier">AI as a Force Multiplier</h3>
<p>Once I have a read on the structure, I’ve started using AI to accelerate specific parts of the audit. I’ve been using thoughtbot’s rails-audit patterns recently — they even have a <a href="https://github.com/thoughtbot/rails-audit-thoughtbot">Claude Code skill</a> now that helps automate the initial pass. A good starting point before you dig into the specifics. Feed it a god model and ask it to identify the distinct responsibilities. Useful for planning a decomposition. Use it to spot patterns across multiple models you’d take longer to see manually.</p>
<p>Here are a few prompts I’ve found useful:</p>
<p><strong>God model decomposition:</strong></p>
<pre>This is a Rails model. List every distinct responsibility you can identify.
Group related methods together and suggest what each group might be extracted into.
</pre>
<p><strong>Callback mapping:</strong></p>
<pre>List every callback in this file, what it does, and what other models or side
effects it might touch. Flag anything that looks like it could cause unexpected
behavior.
</pre>
<p><strong>Plain English summary:</strong></p>
<pre>Explain what this code does in plain English, as if you were explaining it
to a new engineer joining the team.
</pre>
<p><strong>Association audit:</strong></p>
<pre>Review these ActiveRecord associations. Flag any missing dependent: options,
any associations that look like they could produce orphaned records, and any
that seem inconsistent with the rest of the schema.
</pre>
<p><strong>Test coverage gap analysis:</strong></p>
<pre>What are the ten most important things to test in this file, in priority order?
</pre>
<p>One caveat: AI doesn’t know what the business does. It can’t tell you whether the complexity in <code>Order</code> is accidental or load-bearing. That judgment is still yours.</p>
<p>On more modern apps, I also check frontend and deployment posture: whether the app has adopted Hotwire/Turbo or is still running a legacy JS layer, and whether there’s a <code>Dockerfile</code> or Kamal config. Both ship with Rails 8 by default, and their absence in a newer app is worth noting.</p>
<hr /><h2 id="when-a-rails-app-needs-a-rewrite-vs-a-refactor">When a Rails App Needs a Rewrite vs. a Refactor</h2>
<p>This is the call only experience teaches.</p>
<p>The team is scared but they can still name what they’re scared of. Specific fear means they understand the system well enough to know where the bodies are buried. Deploys still happen, even if they’re painful. A team that ships, even reluctantly, is recoverable. There’s a test suite, even a bad one — something is better than nothing. The god models are big but you can trace the logic. Messy doesn’t mean incomprehensible.</p>
<p>The harder conversation looks different. Nobody can explain how a core flow works without reading the code line by line. That’s not complexity — that’s lost knowledge. Deploys have stopped entirely because it’s too unpredictable. There are parts of the system with an unofficial “do not touch” status — not because they’re complex, but because nobody remembers why they work. The test suite takes 90 minutes and fails intermittently, so nobody runs it.</p>
<p>Sometimes the codebase isn’t the problem at all. The business has outgrown the architecture and no amount of cleanup will fix that. A rewrite conversation isn’t about the code being bad. It’s about the cost of continuing to work around it being higher than the cost of starting over.</p>
<p><strong>Signs the codebase is messy but recoverable:</strong></p>
<ul><li>The team can name the scary parts specifically — they have accurate mental maps, just bad terrain</li>
<li>The test suite runs and mostly passes, even if slowly</li>
<li>Deploys happen at a regular cadence, even if they’re tense</li>
<li>A new developer can get the app running from the README in under two hours</li>
</ul><p><strong>Signs you’re actually in trouble:</strong></p>
<ul><li>Deploy frequency has dropped toward zero because “it’s too risky”</li>
<li>Features quietly disabled, never re-enabled</li>
<li>Multiple developers independently describe different parts as “nobody touches that”</li>
<li>No APM, no error tracking, no alerting in production</li>
<li>“I changed one thing and something completely different broke” is a regular occurrence</li>
</ul><p><strong>Note:</strong> This rewrite-vs-refactor evaluation is the core of technical due diligence for acquisitions or investment rounds. It’s the question a buyer or investor most needs answered before committing.</p>
<hr /><h2 id="what-a-rails-audit-should-deliver-the-week-one-report">What a Rails Audit Should Deliver: The Week One Report</h2>
<p>Not a list of everything wrong — that overwhelms and paralyzes. Instead:</p>
<p>Early on, I wrote long reports. Exhaustive findings documents with every RuboCop violation, every outdated gem, every missing index. Color-coded spreadsheets. Clients would nod, say “very thorough,” and file it away. I realized I was putting the burden of prioritization back on them — which is exactly what they hired me to avoid.</p>
<p>What works better is a single page with three sections: fix this week, fix this quarter, don’t worry about it. I also call out a fourth category: things I can fix without touching your team’s current output. Dependency upgrades, security patches, dead code removal, and rewriting parts of the codebase that nobody owns and nobody wants to touch. Work that can happen in parallel without interrupting a sprint or stealing engineering time. Clients love knowing there’s a bucket of real progress that costs them nothing in team bandwidth.</p>
<p>A short verbal debrief before anything written, because the conversation matters more than the document. And leading with the one thing that surprised me most — not the longest list, the most important finding.</p>
<p>The thing that changed how I think about deliverables: I started asking myself “if this team could only fix one thing this year, what should it be?” It forces you to have an opinion, not just a list of observations. Clients hire you for the opinion.</p>
<ul><li><strong>Severity triage:</strong> security/compliance risks that need immediate action, architectural problems slowing development, cosmetic issues that can be addressed over time</li>
<li><strong>The five highest-churn, lowest-coverage files:</strong> the specific things hurting the team right now</li>
<li><strong>Bus factor assessment:</strong> who are the single points of failure?</li>
<li><strong>Version upgrade path:</strong> what it would take, and what it’s costing them not to do it</li>
<li><strong>One honest conversation:</strong> the thing the team suspected but hadn’t said out loud</li>
</ul><hr /><h2 id="quick-reference-command-sequence">Quick-Reference Command Sequence</h2>
<div class="highlight"><pre class="language-bash" data-lang="bash"># Security
bundle audit update &amp;&amp; bundle audit check
bundle exec brakeman --format html -o brakeman_report.html
# Dependency age
bundle outdated
bundle exec bundle_report compatibility --rails-version=7.2
# SLOC + complexity
cloc app/
bundle exec rubycritic app/
# Routes — quick count before you open the file
bundle exec rails routes | wc -l
# Dead routes and orphaned actions
bundle exec traceroute
# Database
bundle exec rails active_record_doctor:run
# Memory
bundle exec derailed bundle:mem
# Test suite
time bundle exec rspec
COVERAGE=true bundle exec rspec
# When was the test suite last touched?
git log --oneline -1 -- spec/
</pre></div>
<hr /><h2 id="faq">FAQ</h2>
<p><strong>How long does a Rails codebase audit take?</strong></p>
<p>The initial signal-reading phase — stakeholder interviews, three-file review, and tool pass — takes roughly one week. A complete written deliverable (severity triage, bus factor assessment, upgrade path) is usually ready by end of week two.</p>
<p><strong>What are the best tools for a Rails security audit?</strong></p>
<p>For security: <code>bundle-audit</code> and Brakeman. For complexity: <code>rubycritic</code> and <code>cloc</code>. For database health: <code>active_record_doctor</code>. For test coverage: SimpleCov. For dependency health: <code>bundle outdated</code> and the <code>next_rails</code> gem.</p>
<p><strong>How do I know if a Rails codebase needs a rewrite vs. a refactor?</strong></p>
<p>If the team can still name specifically what they’re afraid of, it’s usually recoverable. If multiple developers independently say “nobody touches that” about different parts of the system — and deploys have dropped toward zero — you’re having a rewrite conversation.</p>
<p><strong>What should a Rails audit deliverable look like?</strong></p>
<p>A single page with three sections: fix this week, fix this quarter, don’t worry about it. A fourth bucket covers work that can happen in parallel without interrupting a sprint: dependency upgrades, security patches, dead code removal.</p>
<hr /><h2>Related Articles</h2>]]></description>
      <link>https://piechowski.io/post/how-i-audit-a-legacy-rails-codebase/</link>
      <guid>https://piechowski.io/post/how-i-audit-a-legacy-rails-codebase/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[GNU and the AI reimplementations - <antirez>]]></title>
      <description><![CDATA[<pre>Those who cannot remember the past are condemned to repeat it. A sentence that I never really liked, and what is happening with AI, about software projects reimplementations, shows all the limits of such an idea. Many people are protesting the fairness of rewriting existing projects using AI. But, a good portion of such people, during the 90s, were already in the field: they followed the final part (started in the ‘80s) of the deeds of Richard Stallman, when he and his followers were reimplementing the UNIX userspace for the GNU project. The same people that now are against AI rewrites, back then, cheered for the GNU project actions (rightly, from my point of view – I cheered too).
Stallman is not just a programming genius, he is also the kind of person that has a broad vision across disciplines, and among other things he was well versed in the copyright nuances. He asked the other programmers to reimplement the UNIX userspace in a specific way. A way that would make each tool unique, recognizable, compared to the original copy. Either faster, or more feature rich, or scriptable; qualities that would serve two different goals: to make GNU Hurd better and, at the same time, to provide a protective layer against litigations. If somebody would claim that the GNU implementations were not limited to copying ideas and behaviours (which is legal), but “protected expressions” (that is, the source code verbatim), the added features and the deliberate push towards certain design directions would provide a counter argument that judges could understand.
He also asked to always reimplement the behavior itself, avoiding watching the actual implementation, using specifications and the real world mechanic of the tool, as tested manually by executing it. Still, it is fair to guess that many of the people working at the GNU project likely were exposed or had access to the UNIX source code.
When Linus reimplemented UNIX, writing the Linux kernel, the situation was somewhat more complicated, with an additional layer of indirection. He was exposed to UNIX just as a user, but, apparently, had no access to the source code of UNIX. On the other hand, he was massively exposed to the Minix source code (an implementation of UNIX, but using a microkernel), and to the book describing such implementation as well. But, in turn, when Tanenbaum wrote Minix, he did so after being massively exposed to the UNIX source code. So, SCO (during the IBM litigation) had a hard time trying to claim that Linux contained any protected expressions. Yet, when Linus used Minix as an inspiration, not only was he very familiar with something (Minix) implemented with knowledge of the UNIX code, but (more interestingly) the license of Minix was restrictive, it became open source only in 2000. Still, even in such a setup, Tanenbaum protested about the architecture (in the famous exchange), not about copyright infringement. So, we could reasonably assume Tanenbaum considered rewrites fair, even if Linus was exposed to Minix (and having himself followed a similar process when writing Minix).
# What the copyright law really says
To put all this in the right context, let’s zoom in on the copyright's actual perimeters: the law says you must not copy “protected expressions”. In the case of the software, a protected expression is the code as it is, with the same structure, variables, functions, exact mechanics of how specific things are done, unless they are known algorithms (standard quicksort or a binary search can be implemented in a very similar way and they will not be a violation). The problem is when the business logic of the programs matches perfectly, almost line by line, the original implementation. Otherwise, the copy is lawful and must not obey the original license, as long as it is pretty clear that the code is doing something similar but with code that is not cut &amp; pasted or mechanically translated to some other language, or aesthetically modified just to look a bit different (look: this is exactly the kind of bad-faith maneuver a court will try to identify). I have the feeling that every competent programmer reading this post perfectly knows what a *reimplementation* is and how it looks. There will be inevitable similarities, but the code will be clearly not copied. If this is the legal setup, why do people care about clean room implementations? Well, the reality is: it is just an optimization in case of litigation, it makes it simpler to win in court, but being exposed to the original source code of some program, if the exposition is only used to gain knowledge about the ideas and behavior, is fine. Besides, we are all happy to have Linux today, and the GNU user space, together with many other open source projects that followed a similar path. I believe rules must be applied both when we agree with their ends, and when we don’t.
# AI enters the scene
So, reimplementations were always possible. What changes, now, is the fact they are brutally faster and cheaper to accomplish. In the past, you had to hire developers, or to be enthusiastic and passionate enough to create a reimplementation yourself, because of business aspirations or because you wanted to share it with the world at large.
Now, you can start a coding agent and proceed in two ways: turn the implementation into a specification, and then in a new session ask the agent to reimplement it, possibly forcing specific qualities, like: make it faster, or make the implementation incredibly easy to follow and understand (that’s a good trick to end with an implementation very far from others, given the fact that a lot of code seems to be designed for the opposite goal), or more modular, or resolve this fundamental limitation of the original implementation: all hints that will make it much simpler to significantly diverge from the original design. LLMs, when used in this way, don’t produce copies of what they saw in the past, but yet at the end you can use an agent to verify carefully if there is any violation, and if any, replace the occurrences with novel code.
Another, apparently less rigorous approach, but potentially very good in the real world, is to provide the source code itself, and ask the agent to reimplement it in a completely novel way, and use the source code both as specification and in order to drive the implementation as far as possible away from the code itself. Frontier LLMs are very capable, they can use something even to explicitly avoid copying it, and carefully try different implementation approaches.
If you ever attempted something like the above, you know how the “uncompressed copy” really is an illusion: agents will write the software in a very “organic” way, committing errors, changing design many times because of limitations that become clear only later, starting with something small and adding features progressively, and often, during this already chaotic process, we massively steer their work with our prompts, hints, wishes. Many ideas are consolatory as they are false: the “uncompressed copy” is one of those. But still, now the process of rewriting is so simple to do, and many people are disturbed by this. There is a more fundamental truth here: the nature of software changed; the reimplementations under different licenses are just an instance of how such nature was transformed forever. Instead of combatting each manifestation of automatic programming, I believe it is better to build a new mental model, and adapt.
# Beyond the law
I believe that organized societies prosper if laws are followed, yet I do not blindly accept a rule just because it exists, and I question things based on my ethics: this is what allows individuals, societies, and the law itself to evolve. We must ask ourselves: is the copyright law ethically correct? Does the speed-up AI provides to an existing process, fundamentally change the process itself?
One thing that allowed software to evolve much faster than most other human fields is the fact the discipline is less anchored to patents and protections (and this, in turn, is likely as it is because of a sharing culture around the software). If the copyright law were more stringent, we could likely not have what we have today. Is the protection of single individuals' interests and companies more important than the general evolution of human culture? I don’t think so, and, besides, the copyright law is a common playfield: the rules are the same for all. Moreover, it is not a stretch to say that despite a more relaxed approach, software remains one of the fields where it is simpler to make money; it does not look like the business side was impacted by the ability to reimplement things. Probably, the contrary is true: think of how many businesses were made possible by an open source software stack (not that OSS is mostly made of copies, but it definitely inherited many ideas about past systems). I believe, even with AI, those fundamental tensions remain all valid. Reimplementations are cheap to make, but this is the new playfield for all of us, and just reimplementing things in an automated fashion, without putting something novel inside, in terms of ideas, engineering, functionalities, will have modest value in the long run. What will matter is the exact way you create something: Is it well designed, interesting to use, supported, somewhat novel, fast, documented and useful? Moreover, this time the inbalance of force is in the right direction: big corporations always had the ability to spend obscene amounts of money in order to copy systems, provide them in a way that is irresistible for users (free, for many years, for instance, to later switch model) and position themselves as leaders of ideas they didn’t really invent. Now, small groups of individuals can do the same to big companies' software systems: they can compete on ideas now that a synthetic workforce is cheaper for many.
# We stand on the shoulders of giants
There is another fundamental idea that we all need to internalize. Software is created and evolved as an incremental continuous process, where each new innovation is building on what somebody else invented before us. We are all very quick to build something and believe we “own” it, which is correct, if we stop at the exact code we wrote. But we build things on top of work and ideas already done, and given that the current development of IT is due to the fundamental paradigm that makes ideas and behaviors not covered by copyright, we need to accept that reimplementations are a fair process. If they don’t contain any novelty, maybe they are a lazy effort? That’s possible, yet: they are fair, and nobody is violating anything. Yet, if we want to be good citizens of the ecosystem, we should try, when replicating some work, to also evolve it, invent something new: to specialize the implementation for a lower memory footprint, or to make it more useful in certain contexts, or less buggy: the Stallman way.
In the case of AI, we are doing, almost collectively, the error of thinking that a technology is bad or good for software and humanity in isolation. AI can unlock a lot of good things in the field of open source software. Many passionate individuals write open source because they hate their day job, and want to make something they love, or they write open source because they want to be part of something bigger than economic interests. A lot of open source software is either written in the free time, or with severe constraints on the amount of people that are allocated for the project, or - even worse - with limiting conditions imposed by the companies paying for the developments. Now that code is every day less important than ideas, open source can be strongly accelerated by AI. The four hours allocated over the weekend will bring 10x the fruits, in the right hands (AI coding is not for everybody, as good coding and design is not for everybody). Linux device drivers can be implemented by automatically disassembling some proprietary blob, for instance. Or, what could be just a barely maintained library can turn into a project that can be well handled in a more reasonable amount of time.
Before AI, we witnessed the commodification of software: less quality, focus only on the money, no care whatsoever for minimalism and respect for resources: just piles of mostly broken bloat. More hardware power, more bloat, less care. It was already going very badly. It is not obvious nor automatic that AI will make it worse, and the ability to reimplement other software systems is part of a bigger picture that may restore some interest and sanity in our field.</pre>]]></description>
      <link>https://antirez.com/news/162</link>
      <guid>https://antirez.com/news/162</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Amazon holds engineering meeting following AI-related outages | FT]]></title>
      <description><![CDATA[Client Challenge
    <noscript>
      <div class="noscript-container"><div class="noscript-content"><img src="https://www.ft.com/_fs-ch-1T1wmsGaOgGaSxcX/assets/errorIcon.svg" alt="" role="presentation" class="error-icon" />JavaScript is disabled in your browser.<p>Please enable JavaScript to proceed.</p></div></div>
    </noscript>
    <p>A required part of this site couldn’t load. This may be due to a browser
      extension, network issues, or browser settings. Please check your
      connection, disable any ad blockers, or try using a different browser.</p>]]></description>
      <link>https://www.ft.com/content/7cab4ec7-4712-4137-b602-119a44f771de</link>
      <guid>https://www.ft.com/content/7cab4ec7-4712-4137-b602-119a44f771de</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[AI should help us produce better code - Agentic Engineering Patterns]]></title>
      <description><![CDATA[<p>Many developers worry that outsourcing their code to AI tools will result in a drop in quality, producing bad code that's churned out fast enough that decision makers are willing to overlook its flaws.</p><p>If adopting coding agents demonstrably reduces the quality of the code and features you are producing, you should address that problem directly: figure out which aspects of your process are hurting the quality of your output and fix them.</p><p>Shipping worse code with agents is a <em>choice</em>. We can choose to ship code <a href="https://simonwillison.net/guides/agentic-engineering-patterns/code-is-cheap/#good-code">that is better</a> instead.</p><h2 id="avoiding-taking-on-technical-debt">Avoiding taking on technical debt</h2><p>I like to think about shipping better code in terms of technical debt. We take on technical debt as the result of trade-offs: doing things "the right way" would take too long, so we work within the time constraints we are under and cross our fingers that our project will survive long enough to pay down the debt later on.</p><p>The best mitigation for technical debt is to avoid taking it on in the first place.</p><p>In my experience, a common category of technical debt fixes is changes that are simple but time-consuming.</p><ul><li>Our original API design doesn't cover an important case that emerged later on. Fixing that API would require changing code in dozens of different places, making it quicker to add a very slightly different new API and live with the duplication.</li>
<li>We made a poor choice naming a concept early on - teams rather than groups for example - but cleaning up that nomenclature everywhere in the code is too much work so we only fix it in the UI.</li>
<li>Our system has grown duplicate but slightly different functionality over time which needs combining and refactoring.</li>
<li>One of our files has grown to several thousand lines of code which we would ideally split into separate modules.</li>
</ul><p>All of these changes are conceptually simple but still need time dedicated to them, which can be hard to justify given more pressing issues.</p><h2 id="coding-agents-can-handle-these-for-us">Coding agents can handle these for us</h2><p>Refactoring tasks like this are an <em>ideal</em> application of coding agents.</p><p>Fire up an agent, tell it what to change and leave it to churn away in a branch or worktree somewhere in the background.</p><p>I usually use asynchronous coding agents for this such as <a href="https://jules.google.com/">Gemini Jules</a>, <a href="https://developers.openai.com/codex/cloud/">OpenAI Codex web</a>, or <a href="https://code.claude.com/docs/en/claude-code-on-the-web">Claude Code on the web</a>. That way I can run those refactoring jobs without interrupting my flow on my laptop.</p><p>Evaluate the result in a Pull Request. If it's good, land it. If it's almost there, prompt it and tell it what to do differently. If it's bad, throw it away.</p><p>The cost of these code improvements has dropped so low that we can afford a zero tolerance attitude to minor code smells and inconveniences.</p><h2 id="ai-tools-let-us-consider-more-options">AI tools let us consider more options</h2><p>Any software development task comes with a wealth of options for approaching the problem. Some of the most significant technical debt comes from making poor choices at the planning step - missing out on an obvious simple solution, or picking a technology that later turns out not to be exactly the right fit.</p><p>LLMs can help ensure we don't miss any obvious solutions that may not have crossed our radar before. They'll only suggest solutions that are common in their training data but those tend to be the <a href="https://boringtechnology.club">Boring Technology</a> that's most likely to work.</p><p>More importantly, coding agents can help with <strong>exploratory prototyping</strong>.</p><p>The best way to make confident technology choices is to prove that they are fit for purpose with a prototype.</p><p>Is Redis a good choice for the activity feed on a site which expects thousands of concurrent users?</p><p>The best way to know for sure is to wire up a simulation of that system and run a load test against it to see what breaks.</p><p>Coding agents can build this kind of simulation from a single well crafted prompt, which drops the cost of this kind of experiment to almost nothing. And since they're so cheap we can run multiple experiments at once, testing several solutions to pick the one that is the best fit for our problem.</p><h2 id="embrace-the-compound-engineering-loop">Embrace the compound engineering loop</h2><p>Agents follow instructions. We can evolve these instructions over time to get better results from future runs, based on what we've learned previously.</p><p>Dan Shipper and Kieran Klaassen at Every describe their company's approach to working with coding agents as <a href="https://every.to/chain-of-thought/compound-engineering-how-every-codes-with-agents">Compound Engineering</a>. Every coding project they complete ends with a retrospective, which they call the <strong>compound step</strong> where they take what worked and document that for future agent runs.</p><p>If we want the best results from our agents, we should aim to continually increase the quality of our codebase over time. Small improvements compound. Quality enhancements that used to be time-consuming have now dropped in cost to the point that there's no excuse not to invest in quality at the same time as shipping new features. Coding agents mean we can finally have both.</p>]]></description>
      <link>https://simonwillison.net/guides/agentic-engineering-patterns/better-code/#atom-everything</link>
      <guid>https://simonwillison.net/guides/agentic-engineering-patterns/better-code/#atom-everything</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Computational Complexity: Tony Hoare (1934-2026)]]></title>
      <description><![CDATA[<p><i>Turing Award winner and former Oxford professor <a href="https://en.wikipedia.org/wiki/Tony_Hoare">Tony Hoare</a> passed away last Thursday at the age of 92. Hoare is famous for quicksort, ALGOL, Hoare logic and so much more. Jim Miles gives his personal reflections.</i></p><table cellpadding="0" style="margin: auto; border-spacing: 0px;"><tbody><tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvSTdi5rexUms5A0uCuIV72EgjY6hap_Ul1KwUyW1mb-xDB7StvfgP4KLsZySqmf7WyOPQv2qAqZnwUAmmPVQ_XE24g1EGICE7hch44j67cLd2kUc2MwRz87g3Y_uUbOSH9rzULKAYjyKCR4YBZWzTWzZYw1dC53RypJSGWikP5HHZWp0mqcGW/s2500/Jill-and-Tony-Hoare-and-Jim-Miles.jpg"><img border="0" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvSTdi5rexUms5A0uCuIV72EgjY6hap_Ul1KwUyW1mb-xDB7StvfgP4KLsZySqmf7WyOPQv2qAqZnwUAmmPVQ_XE24g1EGICE7hch44j67cLd2kUc2MwRz87g3Y_uUbOSH9rzULKAYjyKCR4YBZWzTWzZYw1dC53RypJSGWikP5HHZWp0mqcGW/s320/Jill-and-Tony-Hoare-and-Jim-Miles.jpg" width="320" alt="image" /></a></td></tr><tr><td>Jill Hoare, Tony Hoare, Jim Miles. Cambridge, 7 September 2021</td></tr></tbody></table><p>Last Thursday (5th March 2026), Tony Hoare passed away, at the age of 92. He made many important contributions to Computer Science, which go well beyond just the one for which most Maths/CompSci undergraduates might know his name: the quicksort algorithm. His achievements in the field are covered comprehensively across easy-to-find books and articles, and I am sure will be addressed in detail as obituaries are published over the coming weeks. I was invited in this entry to remember the Tony that I knew, so here I will be writing about his personality from the occasions that I met him.</p><p>I visited Tony Hoare several times in the past 5 years, as we both live in Cambridge (UK) and it turned out that my family knew his. As a Mathematics graduate, I was very keen to meet and learn about his life from the great man himself. I was further prompted by a <a href="https://blog.computationalcomplexity.org/2021/06/i-went-to-debate-about-program-verif.html">post on this blog</a> which mentioned Tony a few times and summarised a relevant portion of his work. I took a print out of that entry the first time I visited him to help break the ice - it is the green sheet of paper in the picture above.</p><p>Tony read the entry and smiled, clearly recalling very well the material of his that it referenced, and then elaborating a bit, explaining how vastly programs had scaled up in a rather short space of time and how they typically require different methods than many of those he had been developing in the early days.</p><p>I was aware that Tony had studied Classics and Philosophy at university so I was keen to learn how one thing had led to another in the development of his career. He explained that after completing his degree he had been intensively trained in Russian on the Joint Services School for Linguists programme and was also personally very interested in statistics as well as the emerging and exciting world of computers. This meant that after his National Service (which was essentially the JSSL) he took on a job 'demonstrating' a type of early computer, in particular globally, and especially in the Soviet Union. He described the place of these demonstrations as 'fairs' but I suppose we might now call them 'expos'. In a sense, this seemed like a very modest description of his job, when in fact - reading up on Tony's career - he was also involved in the development of code for these devices, but perhaps that's a historical quirk of the period: being a demonstrator of these machines meant really knowing them inside and out to the point of acting on the dev team (AND, one might deduce, being fluent in Russian!).</p><p>Tony would tell these stories with a clarity and warmth that made it clear that certainly he was still entirely 'all there' mentally, and that his memory was pinpoint sharp, even if there were some physical health issues, typical for anyone who makes it so far into their 80s (and, as we now know, beyond!).</p><p>A story that I was determined to hear from the source was the legendary quicksort 'wager'. The story goes that Tony told his boss at Elliott Brothers Ltd that he knew a faster sorting algorithm than the one that he had just implemented for the company. He was told 'I bet you sixpence you don't!'. Lo and behold, quicksort WAS faster. I asked Tony to tell this story pretty much every time we met, because I enjoyed it so much and it always put a smile on both of our faces. To his credit, Tony never tired of telling me this story 'right from the top'. I had hoped to visit again in the past year and record him telling it so that there was a record, but unfortunately this did not happen. However, I discover that it is indeed <a href="https://youtu.be/pJgKYn0lcno?t=201">recorded elsewhere</a>. One detail I might be able to add is that I asked Tony if indeed the wager was paid out or if it had merely been a figure of speech. He confirmed that indeed he WAS paid the wager (!). A detail of this story that I find particularly reflective of Tony's humble personality is that he went ahead and implemented the slower algorithm he was asked to, while he believed quicksort to be faster, and before chiming in with this belief. It speaks to a professionalism that Tony always carried.</p><p>About 50% of our meetings were spent talking about these matters relating to his career, while the rest varied across a vast range of topics. In particular, I wanted to ask him about a story that I had heard from a relative, that Tony - whilst working at Microsoft in Cambridge - would like to slip out some afternoons and watch films at the local Arts Picturehouse. This had come about because on one occasion a current film in question was brought up in conversation and it transpired Tony had seen it, much to the bemusement of some present. The jig was up - Tony admitted that, yes, sometimes he would nip out on an afternoon and visit the cinema. When I met Tony and gently questioned him on this anecdote he confirmed that indeed this was one of his pleasures and his position at Microsoft more than accommodated it.</p><p>On the topic of films, I wanted to follow up with Tony a quote that I have seen online attributed to him about Hollywood portrayal of geniuses, often especially in relation to Good Will Hunting. A typical example is: "Hollywood's idea of genius is Good Will Hunting: someone who can solve any problem instantly. In reality, geniuses struggle with a single problem for years". Tony agreed with the idea that cinema often misrepresents how ability in abstract fields such as mathematics is learned over countless hours of thought, rather than - as the movies like to make out - imparted, unexplained, to people of 'genius'. However, he was unsure where exactly he had said this or how/why it had gotten onto the internet, and he agreed that online quotes on the subject, attributed to him, may well be erroneous.</p><p>One final note I would like to share from these meetings with Tony is perhaps the most intriguing of what he said, but also the one he delivered with the greatest outright confidence. In a discussion about the developments of computers in the future - whether we are reaching limits of Moore's Law, whether Quantum Computers will be required to reinvigorate progress, and other rather shallow and obvious hardware talking points raised by me in an effort to spark Tony's interest - he said 'Well, of course, nothing we have even comes close to what the government has access to. They will always be years ahead of what you can imagine'. When pressed on this, in particular whether he believed such technology to be on the scale of solving the large prime factorisation that the world's cryptographic protocols are based on, he was cagey and shrugged enigmatically. One wonders what he had seen, or perhaps he was engaging in a bit of knowing trolling; Tony had a fantastic sense of humour and was certainly capable of leading me down the garden path with irony and satire before I realised a joke was being made.</p><p>I will greatly miss this humour, patience, and sharpness of mind, as I miss everything else about Tony.</p><p>RIP Tony Hoare (11 January 1934 - 5 March 2026)</p>]]></description>
      <link>https://blog.computationalcomplexity.org/2026/03/tony-hoare-1934-2026.html</link>
      <guid>https://blog.computationalcomplexity.org/2026/03/tony-hoare-1934-2026.html</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[UK Government Network Graph]]></title>
      <description><![CDATA[Organisations, services and operational dependencies across government]]></description>
      <link>https://ukgov-network-graph.lovable.app/</link>
      <guid>https://ukgov-network-graph.lovable.app/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Is legal the same as legitimate: AI reimplementation and the erosion of copyleft | Hacker News]]></title>
      <description><![CDATA[<table border="0" class="comment-tree"><tr class="athing comtr" id="47316829"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jrochkind1" class="hnuser">jrochkind1</a> <a href="https://news.ycombinator.com/item?id=47316829">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; If source code can now be generated from a specification, the specification is where the essential intellectual content of a GPL project resides.
<p>Our foreparents fought for the right to implement works-a-like to corporate software packages, even if the so-called owners did not like it. We're ready to throw it all away, and let intellectual property owners get so much more control.</p>
<p>The implications will not end up being anti-large-corporation or pro-sharing. If you can prevent someone from re-implementing a spec or building a client that speaks your API or building a work-a-like, it will be the large corporations that exersize this power as usual.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318143"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dogcomplex" class="hnuser">dogcomplex</a> <a href="https://news.ycombinator.com/item?id=47318143">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47318743" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">We should be removing IP law entirely, not strengthening it to cover entire classes of problem even when implemented entirely differently. Same for anyone trying to claim "colorful monster creatures" as innately Pokemon IP. Just because someone climbed a mountain first doesn't mean they own it forever. Nobody should be honouring any of these claims.
<p>Nor should we be treating AI models themselves as respected IP. They're built on everyone else's data. Throw away this whole class of law, it's irrelevant in this new world.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318504"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=teaearlgraycold" class="hnuser">teaearlgraycold</a> <a href="https://news.ycombinator.com/item?id=47318504">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318143" class="clicky" aria-hidden="true">parent</a> | <a href="#47318567" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; own it forever
<p>Well we could try fixing the forever part. Copyright is out of control. I’d like to see a world with much less power given to IP. Sometimes I even say I want it eradicated entirely. But realistically we should start by cutting things back. Maybe give software an especially short copyright period.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318988"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=fc417fc802" class="hnuser">fc417fc802</a> <a href="https://news.ycombinator.com/item?id=47318988">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318504" class="clicky" aria-hidden="true">parent</a> | <a href="#47318567" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Reset it back to 20 years and make that a hard limit for both patents and copyright. No renewals. Zero exceptions. Let the market sort the rest out.
<p>There's always going to be downsides and edgecases when granting any party a monopoly over anything. At least if it's limited to 2 decades any unintended consequences, philosophical objections, and etc are hopefully kept within reason.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320214"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Qwertious" class="hnuser">Qwertious</a> <a href="https://news.ycombinator.com/item?id=47320214">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318988" class="clicky" aria-hidden="true">parent</a> | <a href="#47318567" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That would be insane for aerospace software, where you might spend most of that time getting the code <em>certified</em> (required to break the $0 revenue threshold), let alone paying back your costs and then making an actual profit.
<p>Meanwhile, there are cases where copyright of more than 2 years is overkill.</p>
<p>I don't know what, but it seems like we need some sort of mechanism for variable-length IP duration is needed.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320314"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=fc417fc802" class="hnuser">fc417fc802</a> <a href="https://news.ycombinator.com/item?id=47320314">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320214" class="clicky" aria-hidden="true">parent</a> | <a href="#47321299" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is copyright meaningful for aerospace software? I'm largely unfamiliar with that domain but I have trouble imagining that (for example) Boeing cares much about people redistributing or hacking on the control software for a 777. How would that impact their bottom line?
<p>I could understand for medical devices maybe but even then it seems like the software is a tiny part of the overall cost of a given design. A competitor could already do a clean room reimplementation in that case.</p>
<p>But I guess it wouldn't be all that bad if there were a carefully crafted extension for government certified software that was explicitly tied to the length of the certification process.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324001"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pixl97" class="hnuser">pixl97</a> <a href="https://news.ycombinator.com/item?id=47324001">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320314" class="clicky" aria-hidden="true">parent</a> | <a href="#47324298" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The only problem with this certified software exception is I foresee they'll write the law as "expiration timer starts when software has finished certification" then some lobby group will get the regulatory departments to adopt a new process of partial certification where said software is usable in devices but the 'finished certification' never gets reached so the copyright gets dragged out forever.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324298"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=PowerElectronix" class="hnuser">PowerElectronix</a> <a href="https://news.ycombinator.com/item?id=47324298">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320314" class="clicky" aria-hidden="true">parent</a> | <a href="#47324001" class="clicky" aria-hidden="true">prev</a> | <a href="#47321299" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Nope, it falls more under trade secrets than copyright.
<p>If you do something that requires stealing the code (publishing it, selling it, etc) the company can legally fuck you up.</p>
<p>Now, once it's in tbe wind, it becomes almost impossible to pursue from a practical point of view, as any implementer can claim trade secrets to avoid showing you the code.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321299"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ncruces" class="hnuser">ncruces</a> <a href="https://news.ycombinator.com/item?id=47321299">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320214" class="clicky" aria-hidden="true">parent</a> | <a href="#47320314" class="clicky" aria-hidden="true">prev</a> | <a href="#47326282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If certification is the actual cost, you don't need copyright, at all. SQLite is in the public domain. Your moat is the certification itself, not the code.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47332955"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Qwertious" class="hnuser">Qwertious</a> <a href="https://news.ycombinator.com/item?id=47332955">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321299" class="clicky" aria-hidden="true">parent</a> | <a href="#47326282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Certification isn't a moat; either the software is certified as safe/bug-free or it isn't. If it's safe, that just makes it more valuable to pirates.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47333510"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ncruces" class="hnuser">ncruces</a> <a href="https://news.ycombinator.com/item?id=47333510">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47332955" class="clicky" aria-hidden="true">parent</a> | <a href="#47326282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's absurd.
<p>I can't use SQLite for aviation even though it was certified.</p>
<p>I can't even claim FIPS compliance for my software without going through an expensive process, even though I only use FIPS approved primitives.</p>
<p>Building on certified/compliant libraries helps, but their vendors can certainly contractually make me pay for it.</p>
<p>All OSS libraries have a warranty disclaimer; using them according to even those licenses automatically excludes "fitness for a particular purpose."</p>
<p>Why would public domain software be any different?</p>
<p>The moat is the certification process, not the code itself. "I copied this from somewhere after it was already certified" might fast track something, but it's not gonna fly with "certification was good, done."</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326282"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rurban" class="hnuser">rurban</a> <a href="https://news.ycombinator.com/item?id=47326282">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320214" class="clicky" aria-hidden="true">parent</a> | <a href="#47321299" class="clicky" aria-hidden="true">prev</a> | <a href="#47322352" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Wait for the great new times when an AI will certify aerospace, automotive and medical SW. Waiting for that. It will be 1000x better and faster than the existing processes</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322352"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Xirdus" class="hnuser">Xirdus</a> <a href="https://news.ycombinator.com/item?id=47322352">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320214" class="clicky" aria-hidden="true">parent</a> | <a href="#47326282" class="clicky" aria-hidden="true">prev</a> | <a href="#47318567" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Or maybe it shouldn't take 10+ years to certify aerospace software.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322583"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=fc417fc802" class="hnuser">fc417fc802</a> <a href="https://news.ycombinator.com/item?id=47322583">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47322352" class="clicky" aria-hidden="true">parent</a> | <a href="#47318567" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Have you seen the quality of regular software though? And the failure rate of regular physical items? The only reason I trust aircraft is because of the process.
<p>Consider if you will that if some guy were to fly a drone the size of a car that he knocked together in his garage over a residential area people would not accept that. Yet private pilots in cessnas fly over neighborhoods constantly.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318567"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47318567">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318143" class="clicky" aria-hidden="true">parent</a> | <a href="#47318504" class="clicky" aria-hidden="true">prev</a> | <a href="#47322968" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Good news! LLM output cannot be copyrighted. Everything that an LLM produces is automatically, irrevocably, in the public domain.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320807"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vbarrielle" class="hnuser">vbarrielle</a> <a href="https://news.ycombinator.com/item?id=47320807">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318567" class="clicky" aria-hidden="true">parent</a> | <a href="#47321386" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not quite in my opinion. The output of an LLM from a simple prompt falls into the public domain, but if you also give a copyrighted work as input, the mechanistic transformation performed will not alter the original license (same as encoding a video does not change its license).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321258"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=xyzal" class="hnuser">xyzal</a> <a href="https://news.ycombinator.com/item?id=47321258">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320807" class="clicky" aria-hidden="true">parent</a> | <a href="#47324024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Are training data counted as input?
<p>It would be interesting to see a court ruling that the output of LLMs trained on copyleft code are licensed under the GPL ... and all other viral licenses simultaneously</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321788"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Frieren" class="hnuser">Frieren</a> <a href="https://news.ycombinator.com/item?id=47321788">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321258" class="clicky" aria-hidden="true">parent</a> | <a href="#47321902" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Are training data counted as input?
<p>It is quantum legality, to use copyright input is legal or illegal depending on the observer.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47323821"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=N7lo4nl34akaoSN" class="hnuser">N7lo4nl34akaoSN</a> <a href="https://news.ycombinator.com/item?id=47323821">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321788" class="clicky" aria-hidden="true">parent</a> | <a href="#47321902" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Schrodinger's Chat</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321902"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Saline9515" class="hnuser">Saline9515</a> <a href="https://news.ycombinator.com/item?id=47321902">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321258" class="clicky" aria-hidden="true">parent</a> | <a href="#47321788" class="clicky" aria-hidden="true">prev</a> | <a href="#47324024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Unless your llm works by quoting large parts of copyrighted works, reinterpretations of them aren't copyrighted. Because it's not a copy.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322201"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=taneq" class="hnuser">taneq</a> <a href="https://news.ycombinator.com/item?id=47322201">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321902" class="clicky" aria-hidden="true">parent</a> | <a href="#47324024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if the output regurgitates some other legal entity’s boilerplate licence agreement? Is the output automatically licensed to that entity?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322347"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=direwolf20" class="hnuser">direwolf20</a> <a href="https://news.ycombinator.com/item?id=47322347">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47322201" class="clicky" aria-hidden="true">parent</a> | <a href="#47322378" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, the copyright is the colour of the bits, and red bits with a comment saying "these bits are blue" are not blue bits, but you may be prosecuted for fraud.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322378"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cj" class="hnuser">cj</a> <a href="https://news.ycombinator.com/item?id=47322378">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47322201" class="clicky" aria-hidden="true">parent</a> | <a href="#47322347" class="clicky" aria-hidden="true">prev</a> | <a href="#47324024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's wild to me that there haven't been more court cases to answer questions like those being asked in this thread.
<p>No one knows.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324381"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dec0dedab0de" class="hnuser">dec0dedab0de</a> <a href="https://news.ycombinator.com/item?id=47324381">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47322378" class="clicky" aria-hidden="true">parent</a> | <a href="#47324024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's new, fast-moving technology, and the courts are slow and expensive.
<p>It would take two stubborn businesses with a lot of money deciding that it is better to battle it out than focus on their business. Something like IBM v SCO or Oracle v Google.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324024"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=conartist6" class="hnuser">conartist6</a> <a href="https://news.ycombinator.com/item?id=47324024">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320807" class="clicky" aria-hidden="true">parent</a> | <a href="#47321258" class="clicky" aria-hidden="true">prev</a> | <a href="#47321386" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">But we also know from other research that LLMs don't actually do mechanistic translations. Even when they are asked to and say that they did, they're basically rewriting the code from their training data</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321386"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=red_admiral" class="hnuser">red_admiral</a> <a href="https://news.ycombinator.com/item?id=47321386">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318567" class="clicky" aria-hidden="true">parent</a> | <a href="#47320807" class="clicky" aria-hidden="true">prev</a> | <a href="#47318598" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If the LLM output is already someone else's copyrighted work, the LLM doesn't change that?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47331813"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47331813">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321386" class="clicky" aria-hidden="true">parent</a> | <a href="#47322682" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The LLM cannot produce copyrighted work.
<p>If the LLM reproduces a human's copyrighted work, then that copyright still stands. This is, in effect, the same as photocopying someone else's writing. The LLM was trained on the copyrighted work, is incapable of producing new copyrightable work, so if it duplicates the original work then the original author's copyright still stands.</p>
<p>I am not a lawyer</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322682"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=raggi" class="hnuser">raggi</a> <a href="https://news.ycombinator.com/item?id=47322682">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321386" class="clicky" aria-hidden="true">parent</a> | <a href="#47331813" class="clicky" aria-hidden="true">prev</a> | <a href="#47318598" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If that occurs and it’s a substantial enough body of output that it is itself copyrightable and not covered by fair use. Confluence of those conditions is intentionally rare.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318598"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=grensley" class="hnuser">grensley</a> <a href="https://news.ycombinator.com/item?id=47318598">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318567" class="clicky" aria-hidden="true">parent</a> | <a href="#47321386" class="clicky" aria-hidden="true">prev</a> | <a href="#47318727" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Same as it ever was: Either trade secrets or license files that are treated as suggestions.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318727"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lurk2" class="hnuser">lurk2</a> <a href="https://news.ycombinator.com/item?id=47318727">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318567" class="clicky" aria-hidden="true">parent</a> | <a href="#47318598" class="clicky" aria-hidden="true">prev</a> | <a href="#47321507" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if you used the LLM to generate works that were already copyrighted?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319881"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=AnthonyMouse" class="hnuser">AnthonyMouse</a> <a href="https://news.ycombinator.com/item?id=47319881">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318727" class="clicky" aria-hidden="true">parent</a> | <a href="#47319118" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There was a recent case that everyone has been describing as "LLM output can't be copyrighted" but what it actually said was you can't register the AI as the author.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47330500"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47330500">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319881" class="clicky" aria-hidden="true">parent</a> | <a href="#47322252" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This is not true, and I'd love to see some actual citation here.
<p>The courts have repeatedly said that copyright only applies to human creativity. The Supreme Court explicitly said this when they refused to hear the appeal:</p>
<p><a href="https://en.wikisource.org/wiki/Thaler_v._Perlmutter,_Refusal_of_First_Request_for_Reconsideration" rel="nofollow">https://en.wikisource.org/wiki/Thaler_v._Perlmutter,_Refusal...</a></p>
<p>&gt; "We affirm our decision to refuse registration for the Work because it lacks the human authorship necessary to be eligible for copyright protection."</p>
<p>So they're saying that the LLM cannot be the author, <em>because</em> LLMs cannot claim copyright.</p>
<p>The related case about patents is more supportive of the narrative that AIs cannot be authors (see <a href="https://www.cafc.uscourts.gov/opinions-orders/21-2347.OPINION.8-5-2022_1988142.pdf" rel="nofollow">https://www.cafc.uscourts.gov/opinions-orders/21-2347.OPINIO...</a>), specifically: "Here, there is no ambiguity: the Patent Act requires that inventors must be natural persons; that is, human beings."</p>
<p>The patent situation is that the Act says that inventor must be an individual, which the courts are interpreting to mean a human, so the LLM cannot be named as the inventor. So, in this case, yes, this is just saying that an LLM cannot be named as the inventor of a patent. That's not the same thing as the courts are saying with copyrights.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47344895"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=AnthonyMouse" class="hnuser">AnthonyMouse</a> <a href="https://news.ycombinator.com/item?id=47344895">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47330500" class="clicky" aria-hidden="true">parent</a> | <a href="#47322252" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; So they're saying that the LLM cannot be the author, <em>because</em> LLMs cannot claim copyright.
<p>They're saying that the LLM can't be the author.</p>
<p>Now suppose you supply the LLM with a prompt that contains human creativity, it performs a deterministic mathematical transformation on the prompt to produce a derivative text, and you want to copyright that, claiming <em>yourself</em> as the author. What happens then?</p>
<p>If you think the answer is that you can't, how do you distinguish that from what happens when someone writes source code and has a compiler turn it into a binary computer program? Or do you think that e.g. Windows binaries can't be copyrighted because they were compiled by a machine?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47345560"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47345560">23 hours ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47344895" class="clicky" aria-hidden="true">parent</a> | <a href="#47322252" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; What happens then?
<p>The part that the human created, the prompt, can be copyrighted.</p>
<p>The part that the LLM created, cannot be.</p>
<p>Copyright in code works exactly the same way: the source code is copyrighted. The binary code is only copyrighted to the extent that it is derived from the source code. This is well-established.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322252"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bdowling" class="hnuser">bdowling</a> <a href="https://news.ycombinator.com/item?id=47322252">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319881" class="clicky" aria-hidden="true">parent</a> | <a href="#47330500" class="clicky" aria-hidden="true">prev</a> | <a href="#47319118" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Powerful interests want it to be true.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319118"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dataflow" class="hnuser">dataflow</a> <a href="https://news.ycombinator.com/item?id=47319118">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318727" class="clicky" aria-hidden="true">parent</a> | <a href="#47319881" class="clicky" aria-hidden="true">prev</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">IMO the bigger question is how would you even tell if a work was generated by an LLM? There's a ton of code being written out there; the folks who generated it are going to claim they authored it for copyright purposes, and those who want to use it are going to claim it was LLM-generated. So what happens?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321183"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=greyface-" class="hnuser">greyface-</a> <a href="https://news.ycombinator.com/item?id=47321183">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319118" class="clicky" aria-hidden="true">parent</a> | <a href="#47319335" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The alleged author, when bringing a copyright infringement suit, will submit testimony claiming they wrote it. Parties to the suit will have a chance to present arguments and evidence. Then, the claim will be adjudicated by a judge and/or jury.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319335"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=terminalshort" class="hnuser">terminalshort</a> <a href="https://news.ycombinator.com/item?id=47319335">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319118" class="clicky" aria-hidden="true">parent</a> | <a href="#47321183" class="clicky" aria-hidden="true">prev</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That code isn't going to be open source. And if you use someone else's closed source code you are violating laws that have nothing to do with copyright.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319742"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dataflow" class="hnuser">dataflow</a> <a href="https://news.ycombinator.com/item?id=47319742">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319335" class="clicky" aria-hidden="true">parent</a> | <a href="#47319537" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm not sure I understand. I'm not talking about stolen/leaked code here. I'm saying: imagine you claim you're the author of some piece of code. You may or may not have written it with an LLM, but even if so, assume you have the full rights to all the inputs. You post it publicly on GitHub. You don't attach a license, or perhaps you attach a restrictive license that doesn't permit much beyond viewing. Someone comes across your code, finds it brilliant, and wants to use it. If that code was non-copyrightable (such as generated via an LLM), then they're fine doing it without your permission, no? But if that code was copyrightable, then they're not permitted to do so, correct?
<p>So now consider two questions:</p>
<p>1. You actually didn't use an LLM, but they believe &amp; claim you did. Who has the burden of proof to show that you actually own the copyright, and how do they do so?</p>
<p>2. They write new code that you feel is based on yours. They claim they washed it through an LLM, but you don't believe so. Who has the burden of proof here and how do they do so?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47331796"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47331796">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319742" class="clicky" aria-hidden="true">parent</a> | <a href="#47319537" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Good questions.
<p>My take on the answers (I am not a lawyer):</p>
<p>1. You copy their code. They bring a copyright claim (let's assume this isn't a DMCA thing and they're actually bringing a claim to court). Your defence is "the LLM wrote it so no copyright attaches". Since they're asserting their copyright claim, they would have to provide evidence for that claim (same as in any other copyright case), including providing evidence that a human wrote it (which is new, and required to defeat your defence).</p>
<p>2. They copy your code. You bring a copyright case. Their defence is "I used an LLM to wash the code without copying". Since they're not disputing your copyright claim to the original code, you don't have to defend or prove your copyright. But you do have to prove that their code infringes on your copyright, which would mean proving that the LLM copied your code when creating the new code. This has been done before by demonstrating similarity.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319537"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47319537">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319335" class="clicky" aria-hidden="true">parent</a> | <a href="#47319742" class="clicky" aria-hidden="true">prev</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Can you expand on that, please? Which other laws are infringed if you use someone else's closed source code?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319611"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LtWorf" class="hnuser">LtWorf</a> <a href="https://news.ycombinator.com/item?id=47319611">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319537" class="clicky" aria-hidden="true">parent</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You used an illegal leak to train your llm</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319747"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Dylan16807" class="hnuser">Dylan16807</a> <a href="https://news.ycombinator.com/item?id=47319747">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319611" class="clicky" aria-hidden="true">parent</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What makes the leak illegal other than copyright?
<p>The occasional piece of software might be a trade secret, but a person downloading a preexisting leak isn't affected by those laws.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320279"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dataflow" class="hnuser">dataflow</a> <a href="https://news.ycombinator.com/item?id=47320279">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319747" class="clicky" aria-hidden="true">parent</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; What makes the leak illegal other than copyright? The occasional piece of software might be a trade secret, but a person downloading a preexisting leak isn't affected by those laws.
<p>I think 18 U.S.C. § 1832 (a) (3) might answer your question? <a href="https://www.law.cornell.edu/uscode/text/18/1832" rel="nofollow">https://www.law.cornell.edu/uscode/text/18/1832</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47331766"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="400" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47331766">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320279" class="clicky" aria-hidden="true">parent</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">To qualify as a trade secret, you have to actually register it as a trade secret.
<p>Closed-source code is not automatically a trade secret.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47341549"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="440" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dataflow" class="hnuser">dataflow</a> <a href="https://news.ycombinator.com/item?id=47341549">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47331766" class="clicky" aria-hidden="true">parent</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's completely false as far as I'm aware. Where did you see this? A simple web search shows numerous sources to the contrary. Are you confusing them with patents by any chance? <a href="https://en.wikipedia.org/wiki/Trade_secret" rel="nofollow">https://en.wikipedia.org/wiki/Trade_secret</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47345586"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="480" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=marcus_holmes" class="hnuser">marcus_holmes</a> <a href="https://news.ycombinator.com/item?id=47345586">23 hours ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47341549" class="clicky" aria-hidden="true">parent</a> | <a href="#47325210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Huh, TIL something new. I was sure they had to be registered. Thanks for the correction :)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47325210"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wk_end" class="hnuser">wk_end</a> <a href="https://news.ycombinator.com/item?id=47325210">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318727" class="clicky" aria-hidden="true">parent</a> | <a href="#47319118" class="clicky" aria-hidden="true">prev</a> | <a href="#47321507" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is Pierre Menard really the author of his Quixote?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321507"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=raxxorraxor" class="hnuser">raxxorraxor</a> <a href="https://news.ycombinator.com/item?id=47321507">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318567" class="clicky" aria-hidden="true">parent</a> | <a href="#47318727" class="clicky" aria-hidden="true">prev</a> | <a href="#47322968" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">I think it can be copyrighted or is a very complex legal issue. Coding support is used in commercial apps where copyrights are fully reserved. I cannot be feasibly determined if any output is purely LLM or not.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322968"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=giancarlostoro" class="hnuser">giancarlostoro</a> <a href="https://news.ycombinator.com/item?id=47322968">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318143" class="clicky" aria-hidden="true">parent</a> | <a href="#47318567" class="clicky" aria-hidden="true">prev</a> | <a href="#47319603" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I would be okay with just keeping it but limiting it severely. If you release music and you can't sell enough albums in 20 years, that's not societies problem. A lot of artists release albums every 1 - 3 years anyway, so they're always selling some records, or were before streaming became the way to "own" music. Most make their money off of concerts anyway.
<p>For movies and shows, charge and increasing fee to renew the copyright. Eventually studios will give up certain movies. The older the movie the more you pay.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324321"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dec0dedab0de" class="hnuser">dec0dedab0de</a> <a href="https://news.ycombinator.com/item?id=47324321">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47322968" class="clicky" aria-hidden="true">parent</a> | <a href="#47319603" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">We could also just have some of the rights go away after X amount of years. Maybe after so much time it's still not legal to copy the original work, but it is legal to make a cover song, or a derivative work using the same character. At another point maybe it's no longer to illegal to copy for free, but it is still illegal to sell without permission.
<p>I personally think we should have shorter limits for non-creator owners of copyright, and for creators it should be like 20 years or death whichever comes last. I also think compulsory licensing should exist for everything.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319603"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LtWorf" class="hnuser">LtWorf</a> <a href="https://news.ycombinator.com/item?id=47319603">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318143" class="clicky" aria-hidden="true">parent</a> | <a href="#47322968" class="clicky" aria-hidden="true">prev</a> | <a href="#47319970" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The problem here is that large companies can do whatever they want and regular people cannot. Don't worry, they won't be allowing you the same rights as these companies.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319970"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jongjong" class="hnuser">jongjong</a> <a href="https://news.ycombinator.com/item?id=47319970">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318143" class="clicky" aria-hidden="true">parent</a> | <a href="#47319603" class="clicky" aria-hidden="true">prev</a> | <a href="#47318743" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">But some people designed their entire lives around the assumption of IP protections.
<p>If we remove IP laws, we should remove all private property laws!</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318743"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thayne" class="hnuser">thayne</a> <a href="https://news.ycombinator.com/item?id=47318743">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47318143" class="clicky" aria-hidden="true">prev</a> | <a href="#47316940" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yeah, I really don't think we want APIs to be protected by IP. But in this case it isn't just the API, there were also tests involved. I think you could make a pretty strong argument that if you used a test suite to get an agent to implement some code, the code is a derivative product of the test code.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322375"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=direwolf20" class="hnuser">direwolf20</a> <a href="https://news.ycombinator.com/item?id=47322375">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318743" class="clicky" aria-hidden="true">parent</a> | <a href="#47319214" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I really don't think a book is a derivative work of the AI model you used to proofread it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr coll" id="47319214"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks nosee">
<div class="c7"><img src="https://news.ycombinator.com/s.gif" height="1" width="14" alt="image" /></div>
</td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/item?id=47319214">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318743" class="clicky" aria-hidden="true">parent</a> | <a href="#47322375" class="clicky" aria-hidden="true">prev</a> | <a href="#47316940" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[3 more]</a></div>
<br /><div class="comment noshow">[dead]
<div class="reply">
</div>
</div></td>
</tr></table></td>
</tr><tr class="athing comtr noshow" id="47321792"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dTal" class="hnuser">dTal</a> <a href="https://news.ycombinator.com/item?id=47321792">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319214" class="clicky" aria-hidden="true">parent</a> | <a href="#47319915" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What exactly is the difference between "a machine-readable contract for what the output has to be" and "source code"?
<p>What is the difference between an "agent" and a "compiler"?</p>
<p>For that matter, what is the difference between "I got an agent to provide a high level description" and a <em>de</em>compiler?</p>
<p>What is the difference between ["decompiling" a binary, editing the resulting source, recompiling, and redistributing] and [analyzing the behavior of a binary, feeding that description into an LLM, generating source code that replicates that behavior, editing <em>that</em>, recompiling and redistributing]?</p>
<p>Takeaway: we are now in a world where software tools can climb up and down the abstraction stack willy nilly and independently of human effort. Legal tools that attempt to track the "provenance" of "source code" were already shaky but are now crumbling entirely.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr noshow" id="47319915"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=AnthonyMouse" class="hnuser">AnthonyMouse</a> <a href="https://news.ycombinator.com/item?id=47319915">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319214" class="clicky" aria-hidden="true">parent</a> | <a href="#47321792" class="clicky" aria-hidden="true">prev</a> | <a href="#47316940" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">One of the interesting things here is that copyright is for expression and patent is for function. You can't copyright function.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316940"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=RobRivera" class="hnuser">RobRivera</a> <a href="https://news.ycombinator.com/item?id=47316940">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47318743" class="clicky" aria-hidden="true">prev</a> | <a href="#47326372" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sounds very similar to that whole API lawsuit with oracle.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316992"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=halJordan" class="hnuser">halJordan</a> <a href="https://news.ycombinator.com/item?id=47316992">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316940" class="clicky" aria-hidden="true">parent</a> | <a href="#47326372" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">And the whole Adobe pdf thing and the whole Microsoft word thing. And the whole ibm pc thing. Imagine if we were forced to keep using ibm from when they lost their way until now simply because anti-ai luddites were able to scare monger</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317113"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dimitrios1" class="hnuser">dimitrios1</a> <a href="https://news.ycombinator.com/item?id=47317113">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316992" class="clicky" aria-hidden="true">parent</a> | <a href="#47326372" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I would wager that the vast majority of people commenting here about the pitfalls of AI, especially as it relates to governance and laws, are heavy users of AI, recognize the import and value it brings, and find ways to utilize it more themselves, so not sure using an ad-hominem dismissal of very valid objections are going to be effective.
<p>(side bar: the phrase "anti-&lt;whatever&gt; luddites" is <em>way, way</em> overused, especially here. Let's get more creative, people!)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319019"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=fc417fc802" class="hnuser">fc417fc802</a> <a href="https://news.ycombinator.com/item?id=47319019">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47317113" class="clicky" aria-hidden="true">parent</a> | <a href="#47317669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">And yet the term luddite seems to fit the anti-ai crowd perfectly. They are largely concerned about employment (and more generally economic stability) and to that end seek measures intended to protect workers.
<p>There's also some environmentalist concerns which the term luddite again fits perfectly. You just have to generalize, transferring laterally from economic wellbeing to environmental wellbeing.</p>
<p>So I don't think GP qualified as an ad hominem dismissal but rather an accurate description of the situation. Take what's being discussed (restrictions on specifications and interoperability), project it backwards in history, and imagine what an alternate present day would look like. I think it would be pretty bad.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320253"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Qwertious" class="hnuser">Qwertious</a> <a href="https://news.ycombinator.com/item?id=47320253">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319019" class="clicky" aria-hidden="true">parent</a> | <a href="#47322449" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;They are largely concerned about employment (and more generally economic stability) and to that end seek measures intended to protect workers.
<p>Pffft no. Most of us think that AI is being used as a political trick - like firing unionized workers "to replace them with AI" and then hiring new un-unionized workers to replace them, 2 weeks later. Replace the AI with an empty cardboard box labeled "AI" in black marker, and nothing changes.</p>
<p>See also: using AI to launder pirated material, for big businesses.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324069"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pixl97" class="hnuser">pixl97</a> <a href="https://news.ycombinator.com/item?id=47324069">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47320253" class="clicky" aria-hidden="true">parent</a> | <a href="#47322449" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;a political trick - like firing unionized workers
<p>1. Since when have companies needed trillions of dollars of AI to do that? In the US they've been able to get away with getting rid of unions for decades now.</p>
<p>2. Since when has HN given a shit about unions. Posting about unions, at least till recently has been a great way of getting your comment downvoted to [dead] in one easy step. For longer than LLMs have existed the HN answer to unions was "They are just there to keep me as an SWE from making as much money as I can". Only now do we see a little bit of pushback now that their heads may be next on the chopping block.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322449"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pyrale" class="hnuser">pyrale</a> <a href="https://news.ycombinator.com/item?id=47322449">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319019" class="clicky" aria-hidden="true">parent</a> | <a href="#47320253" class="clicky" aria-hidden="true">prev</a> | <a href="#47317669" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; and more generally economic stability
<p>Who doesn't enjoy <em>interesting times</em>™</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317669"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=MrDarcy" class="hnuser">MrDarcy</a> <a href="https://news.ycombinator.com/item?id=47317669">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47317113" class="clicky" aria-hidden="true">parent</a> | <a href="#47319019" class="clicky" aria-hidden="true">prev</a> | <a href="#47326372" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c88">HN comments on LLM agents are bi-modal now, as are views in the general population. The modes are adopters and non-adopters.
<p>There isn’t much of a middle ground anymore.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326372"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=glhaynes" class="hnuser">glhaynes</a> <a href="https://news.ycombinator.com/item?id=47326372">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47316940" class="clicky" aria-hidden="true">prev</a> | <a href="#47321531" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It'd be interesting (earnestly!) to see someone make a solid case for AI reimplementation being bad but that the original (afaik) "clean room" project, Compaq's reimplementation of IBM's PC BIOS (something most people seem to see as a righteous move toward openness and freedom), was good.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321531"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=noemit" class="hnuser">noemit</a> <a href="https://news.ycombinator.com/item?id=47321531">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47326372" class="clicky" aria-hidden="true">prev</a> | <a href="#47321120" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Copyright has always benefited those with power, down to the very first instance: Albrecht Durer bullying little children who wanted to make inferior copies of his prints so that their familities could enjoy the art. Durer insisted the art was only for nobles. Ab initio</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321120"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zelphirkalt" class="hnuser">zelphirkalt</a> <a href="https://news.ycombinator.com/item?id=47321120">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47321531" class="clicky" aria-hidden="true">prev</a> | <a href="#47318780" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It is not aout throwing the right to implement things away. As long as it is done according to the license of the works modified or copied, one can do that. What this is against is, that people wash away a license, that is meant to keep things open, transparent and free. It enables businesses to go back to completely proprietary systems, which will impact your rights.
<p>I am for keeping the licenses in place, as long as there is any copyright at all on software. If we get rid of that, then we can get rid of copyleft licenses and all others too. But of course businesses and greedy people want to have their cake and eat it too. They want copyleft to disappear, but _their_ software, oh no, no one may copy that! Double standards at their best.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321186"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rcxdude" class="hnuser">rcxdude</a> <a href="https://news.ycombinator.com/item?id=47321186">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47321120" class="clicky" aria-hidden="true">parent</a> | <a href="#47318780" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You're asking for exactly the same cake. You want for the GPL to pass through this process, but not the proprietary licenses that the original GNU tools were washing away.
<p>(the paradox of copyleft is that it does tend to push free software advocates in a direction of copyright maximalism)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318780"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thayne" class="hnuser">thayne</a> <a href="https://news.ycombinator.com/item?id=47318780">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47321120" class="clicky" aria-hidden="true">prev</a> | <a href="#47330694" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if there was a special exemption for using a specification if you open source (or open hardware) the result for some definition roughly (or exacactly) equivalent to the OSI definition of open source, or FSFs definition of free software?
<p>Although I think the chance of that happening is effectively zero.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47330694"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Ferret7446" class="hnuser">Ferret7446</a> <a href="https://news.ycombinator.com/item?id=47330694">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47318780" class="clicky" aria-hidden="true">prev</a> | <a href="#47321566" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Our foreparents of FOSS (e.g. RMS) fought to destroy copyright. Copyleft was a subversive mechanism to "neutralize" copyright using the laws of copyright against itself.
<p>Hypothetically, I think this trail of suggestion of treating specs as intellectual property would simply destroy copyright for software, which is what we (the people who believe in FOSS) want. There is already case law protecting specs (e.g. Java)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47330985"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pabs3" class="hnuser">pabs3</a> <a href="https://news.ycombinator.com/item?id=47330985">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47330694" class="clicky" aria-hidden="true">parent</a> | <a href="#47321566" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">RMS fought for user freedom, not to destroy copyright. Copyleft wasn't to neutralize copyright, but to ensure user freedom for downstream users.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321566"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=red_admiral" class="hnuser">red_admiral</a> <a href="https://news.ycombinator.com/item?id=47321566">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47330694" class="clicky" aria-hidden="true">prev</a> | <a href="#47322993" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The specification of chardet, which started this all off, is essentially forced by the unicode statndard though.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322993"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=az226" class="hnuser">az226</a> <a href="https://news.ycombinator.com/item?id=47322993">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47321566" class="clicky" aria-hidden="true">prev</a> | <a href="#47316907" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">SCOTUS ruled on this already when Google copied Sun’s Java wholesale.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47323108"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mikkupikku" class="hnuser">mikkupikku</a> <a href="https://news.ycombinator.com/item?id=47323108">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47322993" class="clicky" aria-hidden="true">parent</a> | <a href="#47316907" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oracle's Java. Oracle bought Sun, including Java, then started throwing lawsuits over something they didn't even make. IP is absurd.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316907"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47316907">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">parent</a> | <a href="#47322993" class="clicky" aria-hidden="true">prev</a> | <a href="#47315293" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c88"><em>&gt;Our foreparents fought for the right to implement works-a-like to corporate software packages, even if the so-called owners did not like it</em>
<p>Our "foreparents" weren't competing with corporations with unlimited access to generative AI trained <em>on their work</em>. The times, they're-a-changin'.</p>
<p>You're rehashing the argument made in one of the articles which this piece criticizes and directly addresses, while ignoring the entirety of what was written before the conclusion that you quoted.</p>
<p>If anyone finds themselves agreeing with the comment I'm responding to, please, do yourself a favor and read the linked article.</p>
<p>I would do no justice to it by reiterating its points here.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317176"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hathawsh" class="hnuser">hathawsh</a> <a href="https://news.ycombinator.com/item?id=47317176">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316907" class="clicky" aria-hidden="true">parent</a> | <a href="#47317488" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I believe the GP post is saying that if we react to the new AI-enabled environment by arbitrarily strengthening IP controls for IP owners, the greatest benefactors will almost certainly be lawyer-laden corporations, not communities, artists, or open source projects. That seems like a reasonable argument.
<p>It seems like the answer is to adjust IP owner rights very carefully, if that's possible. It sounds very hard, though.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr coll" id="47318273"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks nosee">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47318273">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47317176" class="clicky" aria-hidden="true">parent</a> | <a href="#47317488" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[1 more]</a></div>
<br /><div class="comment noshow">
<div class="commtext c73">The article makes the same point; the quote was taken out of context.
<p>The point the author was making was that the intent of GPL is to shift the balance of power <em>from</em> wealthy corporations <em>to</em> the commons, and that the spirit is to make contributing to the commons an activity where you feel <em>safe</em> in knowing that your contributions won't be exploited.</p>
<p>The corporations today have the resources to purchase AI compute to produce AI-laundered work, which wouldn't be possible without the commons the AI it got its training data from, and give nothing back to the commons.</p>
<p>This state of things disincentivizes contributing to the FOSS ecosystem, as your work <em>will</em> be taken advantage of while the commons gets nothing.</p>
<p>Share-alike clause of the GPL was the price that was set for benefitting from the commons.</p>
<p>Using LLMs trained on GPL code to x "reimplement" it creates a legal (but not a moral!) workaround to circumvent GPL and avoid paying the price for participation.</p>
<p>This means that the current iteration of GPL isn't doing its intended job.</p>
<p>GPL had to grow and evolve. The Internet services using GPL code to provide access to software without, technically, <em>distributing</em> it was a similar legal (but not moral) workaround which was addressed with an update in GPL.</p>
<p>The author argues that we have reached another such point. They don't argue what exactly needs to be updated, or how.</p>
<p>They bring up a suggestion to make copyrightable the <em>input to the LLM</em> which is sufficient to create a piece of software, because in the current legal landscape, creating the <em>prompt</em> is deemed equivalent to creating the <em>output</em>.</p>
<p>You can't have your cake and eat it too.</p>
<p>A vibe-coded API implementation created by an LLM trained on open source, GPL licensed code can only be considered <em>one</em> of two things:</p>
<p>— Derivative work, and therefore, subject to the requirement to be shared under the GPL license (something the legal system disagrees with)</p>
<p>— An original work of the <em>person</em> who entered the prompt into the LLM, which is <em>a transformative fair use</em> of the training set (the current position of the legal system).</p>
<p>In the later case, the input to the LLM (which <em>must</em> include a reference to the API) is effectively deemed to be equivalent to the output.</p>
<p>The vibe-coded app, the reasoning goes, isn't a photocopy of the training data, but a rendition of the prompt (even though the transformativeness came entirely from the machine and not the "author").</p>
<p>Personally, I don't see a difference between making a photocopy by scanning and printing, and by "reimplementing" API by vibe coding. A photocopy looks different under a microscope too, and is clearly distinguishable from the original. It can be made <em>better</em> by turning the contrast up, and by shuffling the colors around. It can be printed on glossy paper.</p>
<p>But the courts see it differently.</p>
<p>Consequently, the legal system <em>currently</em> decided that writing the prompt <em>is</em> where all the originality and creative value is.</p>
<p>Consequently, <em>de facto</em>, the API is the <em>only</em> part of an open source program that has <em>can</em> be protected by copyright.</p>
<p>The author argues that perhaps it should be — <em>to start a conversation</em>.</p>
<p>As for who the benefactors are from a change like that — that, too, is not clear-cut.</p>
<p>The entities that benefit the most from LLM use are the corporations which can afford the compute.</p>
<p>It isn't that cheap.</p>
<p>What has changed since the first days of GPL is precisely this: the cost of <em>implementing</em> an API has gone down asymmetrically.</p>
<p>The importance of having an open-source compiler was that it put corporations and contributors the commons on equal footing when it came to implementation.</p>
<p>It would take an engineer the same amount of time to implement an API whether they do it for their employer or themselves. And whether they write a piece of code for work or for an open-source project, the expenses are the same.</p>
<p>Without an open compiler, that's not possible. The engineer having access to the compiler at work would have an infinite advantage over an engineer who doesn't have it at home.</p>
<p>The LLM-driven AI today takes the same spot. It's become the tool that software engineers can and <em>do</em> use to produce work.</p>
<p>And the LLMs are neither open nor cheap. Both creating them <em>as well as</em> using them at scale is a privilege that only wealthy corporations can afford.</p>
<p>So we're back to the days before the GNU C compiler toolchain was written: the <em>tools</em> aren't free, and the corporations have effectively unlimited access to them compared to enthusiasts.</p>
<p>Consequently, locking down the implementation of public APIs will <em>asymmetrically</em> hurt the corporations more than it does the commons.</p>
<p>This asymmetry is at the core of GPL: being forced to share something for free doesn't at all hurt the developer who's doing it willingly in the first place.</p>
<p>Finally, looking back at the old days ignores the reality. Back in the day, the proprietary software established the APIs, and the commons grew by reimplementing them to produce viable substitutes.</p>
<p>The commons did not even <em>have</em> its own APIs worth talking about in the early 1990s. But the commons grew way, way past that point since then.</p>
<p>And the value of the open source software is currently not in the fact that you can hot-swap UNIX components with open source equivalents, but in the entire <em>interoperable ecosystem</em> existing.</p>
<p>The APIs of open source programs are where the <em>design</em> of this enormous ecosystem is encoded.</p>
<p>We can talk about <em>possible</em> negative outcomes from pricing it.</p>
<p>Meanwhile, the <em>already happening</em> outcome is that a large corporation like Microsoft can throw a billion dollars of compute on "creating" MSLinux and refabricating the <em>entire FOSS ecosystem</em> under a proprietary license, enacting the Embrace, Extend, Extinguish strategy they never quite abandoned.</p>
<p>It simply didn't make sense for a large corporation to do that earlier, because it's very hard to compete with free labor of open source contributors on cost. It would not be a justifiable expenditure.</p>
<p>What GPL had accomplished in the past was ensuring that <em>Embracing</em> the commons led to <em>Extending</em> it without <em>Extinguishing</em>, by a Midas touch clause. Once you embrace open source, you are it.</p>
<p>The author of the article asks us to think about <em>how</em> GPL needs to be modified so that <em>today</em>, embracing and extending open-source solutions wouldn't lead to commons being <em>extinguished</em>.</p>
<p>Which is exactly what happened in the case of the formerly-GPL library in question.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317488"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sobellian" class="hnuser">sobellian</a> <a href="https://news.ycombinator.com/item?id=47317488">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316907" class="clicky" aria-hidden="true">parent</a> | <a href="#47317176" class="clicky" aria-hidden="true">prev</a> | <a href="#47317798" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think the article in fact reaches the exact opposite conclusion it should. I'm not really sure how useful it is to talk about sharing and commons and morals when the point raised was about what is possible. The prescription includes copyleft APIs. These are not possible under Oracle v Google. And you could point it out if I'm wrong but the article doesn't discuss what would happen if Congress acted to reverse Oracle v Google (IMO a cosmically bad idea).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317798"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47317798">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316907" class="clicky" aria-hidden="true">parent</a> | <a href="#47317488" class="clicky" aria-hidden="true">prev</a> | <a href="#47317160" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Adding even more intellectual property nonsense isn't going to work. The <em>real</em> solution is to force AI companies to open up their models to all. We need <em>free as in freedom LLMs</em> that we can run locally on our own computers.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318458"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=trinsic2" class="hnuser">trinsic2</a> <a href="https://news.ycombinator.com/item?id=47318458">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47317798" class="clicky" aria-hidden="true">parent</a> | <a href="#47318320" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree. But IMHO that ship has sailed. This should have been stop it when OpenAI went for-profit.
<p>If you want to build a new world with out this, we can't do it while we are supporting the very companies that are creating the problem. The more power you give them, the strong they get and the weaker we become.</p>
<p>I think focus needs to shift completely off of for-profit companies. Although, not sure how that is going to happen..lol</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318320"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=autoexec" class="hnuser">autoexec</a> <a href="https://news.ycombinator.com/item?id=47318320">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47317798" class="clicky" aria-hidden="true">parent</a> | <a href="#47318458" class="clicky" aria-hidden="true">prev</a> | <a href="#47318335" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Force them to open (and host) all their training data. They stole it from the pubic to sell it back to us anyway.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318335"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47318335">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47317798" class="clicky" aria-hidden="true">parent</a> | <a href="#47318320" class="clicky" aria-hidden="true">prev</a> | <a href="#47317160" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt;Adding even more intellectual property nonsense isn't going to work.</em>
<p>[citation needed]</p>
<p>Where does your confidence come from?</p>
<p>GPL itself was precisely the "intellectual property nonsense" adding which made FOSS (free as in freedom) software <em>possible</em>.</p>
<p>The copyright law was awfully broken in the 1980s too. Adding "nonsense" then was the only solution that proved viable.</p>
<p>Historically, nothing <em>but</em> adding "more IP nonsense" has <em>ever</em> worked.</p>
<p>&gt;<em>The real solution is to force AI companies to open up their models to all.</em></p>
<p>Sure. Pray tell <em>how</em> you would do that without some "intellectual property nonsense".</p>
<p>We don't exactly get to hold Sam Altman at gunpoint to dictate our terms.</p>
<p>&gt;<em>We need free as in freedom LLMs that we can run locally on our own computers</em></p>
<p>Oh, on that note.</p>
<p>LLMs take a <em>fuckton</em> of compute to train and to even <em>run</em>.</p>
<p>Even if all models were open, we're not at the point where it would create an equal playing field.</p>
<p>My home computer and my dev machine at work have the same specs. But I don't have a compute farm to run a ChatGPT on.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318480"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47318480">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318335" class="clicky" aria-hidden="true">parent</a> | <a href="#47317160" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Where does your confidence come from?
<p>From the fact that copyright infringement is trivial and done at massive scales by pretty much everyone on a daily basis without people even realizing it. You infringe copyright every time you download a picture off of a website. You infringe copyright every time you share it with a friend. Everybody does stuff like this every single day. Nobody cares. It is <em>natural</em>.</p>
<p>&gt; GPL itself was precisely the "intellectual property nonsense"</p>
<p>Yes. In response to copyright protection being extended towards software. It's a legal hack, nothing more. The ideal situation would have been to have no copyright to begin with. The corporation can copy your code but you can copy theirs too. Fair.</p>
<p>&gt; Pray tell <em>how</em> you would do that without some "intellectual property nonsense".</p>
<p>Intellectual property is irrelevant to AI companies.</p>
<p>Intellectual property is built on top of a fundamental delusion: the idea that you can <em>publish</em> information and simultaneously control what people do with it. It's quite simply <em>delusional</em> to believe you can control what people do with information once it's out there and circulating. The tyranny required to implement this amounts to totalitarian dictatorships.</p>
<p>If you want to control information, then your only hope is to <em>not</em> publish it. Like cryptographic keys, the ideal situation is the one where only a single copy of the information exists in the entire universe.</p>
<p>AI companies are not publishing any information. They are keeping their models secret, under lock and key. They need exactly zero intellectual property protection. In fact such protections have negative value to them since it restricts the training of their models.</p>
<p>&gt; We don't exactly get to hold Sam Altman at gunpoint to dictate our terms.</p>
<p>Sure you do. The whole point of government is to do just that. Literally pass some kind of law that forces the corporations to publish the model weights. And if the government refuses to do it, people can always rise up.</p>
<p>&gt; Even if all models were open, we're not at the point where it would create an equal playing field.</p>
<p>Hopefully we will be, in the future.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319785"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway290" class="hnuser">throwaway290</a> <a href="https://news.ycombinator.com/item?id=47319785">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318480" class="clicky" aria-hidden="true">parent</a> | <a href="#47318773" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c88">&gt; You infringe copyright every time you download a picture off of a website. You infringe copyright every time you share it with a friend.
<p>respectfully yoy have no idea what you are talking about here.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324140"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pixl97" class="hnuser">pixl97</a> <a href="https://news.ycombinator.com/item?id=47324140">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319785" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Why don't they, there have been lawsuits over just these behaviors in the past. Hell, even the multiple representations of the picture in computer memory have had to have allowances.
<p>Copyright is a gigantic fucking mess that the US has forced over a large chunk of the world.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47325599"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway290" class="hnuser">throwaway290</a> <a href="https://news.ycombinator.com/item?id=47325599">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47324140" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; there have been lawsuits over just these behaviors in the past
<p>How did they turn out?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326744"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pixl97" class="hnuser">pixl97</a> <a href="https://news.ycombinator.com/item?id=47326744">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47325599" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It depends if you count the ones that were settled behind NDAs with large companies with unknown amounts being paid out that are ticking time bombs waiting to go off in the future.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47332896"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway290" class="hnuser">throwaway290</a> <a href="https://news.ycombinator.com/item?id=47332896">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47326744" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">let's just count the ones we know about? you sound evasive;)
<p>Remember the original poster said that any time my browser downloads a picture on any website (which is a technical requirement to show it) I am infringing on those rights. If that is US court opinioon that would be absolutely stupid.</p>
<p>Of course if you reshare some work that actually is somebody's property you can be totally infringing. Which makes total sense. Except when big tech does the same to us (LLM and diffusion training) it's suddenly ok and that's insane</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47344638"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="400" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47344638">1 day ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47332896" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Copyright is the right to make copies. The creator of a work has a government granted monopoly on that right.
<p>When I download a picture from a website and save it to my machine, I am making a copy of it. If the photographer has not given me explicit permission to do so, then I have infringed on their rights by making an unauthorized copy of their work.</p>
<p>The mere existence of licenses like the creative commons refutes your argument. They would not be necessary if you could just download whatever without infringing copyrights.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47349454"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="440" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway290" class="hnuser">throwaway290</a> <a href="https://news.ycombinator.com/item?id=47349454">13 hours ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47344638" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Downloading a picture needs to happen to show it. Without it it cannot be shown. I'm sure courts figured out that viewing a picture via browser is not infringing.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47357041"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="480" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47357041">4 hours ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47349454" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You forgot the "save it to my machine" part which lets me view the picture whenever I want without visiting its creator's website repeatedly. This means I don't need to be exposed to ads, which in turn lowers the creator's income. It also means other people can get the picture from me rather from the creator. Even less ads and payments.
<p>Obviously the creators want more money and control. Thus copies are only allowed to be made if it benefits them. Viewing a copy of the picture via the website might be permitted, but saving it or sharing it might not.</p>
<p>The truth is nobody really cares what creators want. People will save and share and edit and meme it all up because they can. It is <em>natural</em>. It is their delusional belief that they can control what others do with information that is out of touch with reality.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320886"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=scheeseman486" class="hnuser">scheeseman486</a> <a href="https://news.ycombinator.com/item?id=47320886">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319785" class="clicky" aria-hidden="true">parent</a> | <a href="#47324140" class="clicky" aria-hidden="true">prev</a> | <a href="#47320164" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You might be thinking of fair use, but that's an affirmative defence. Every time someone has copied someone elses artwork and modified it into a meme, that's copyright infringement and remains so even if is eventually ruled as fair use. If you make a fair use claim, you don't deny infringement, you make the claim that you were allowed to infringe.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320164"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47320164">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319785" class="clicky" aria-hidden="true">parent</a> | <a href="#47320886" class="clicky" aria-hidden="true">prev</a> | <a href="#47318773" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Try replacing "picture" with "music file".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318773"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=salawat" class="hnuser">salawat</a> <a href="https://news.ycombinator.com/item?id=47318773">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318480" class="clicky" aria-hidden="true">parent</a> | <a href="#47319785" class="clicky" aria-hidden="true">prev</a> | <a href="#47317160" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">So... People are going to rise up? What makes you think most of them have enough slack in their finances to pack up and haul off to D.C.? Only the Elites do, and they pay full time lobbyists to do exactly that to make sure laws like you mention never pass. Not saying it can't work. Just saying it the game is rigged against the very people you want to rise up and in favor of the ones who'd rather you stayed in bed.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319094"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47319094">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47318773" class="clicky" aria-hidden="true">parent</a> | <a href="#47317160" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If people don't rise up they will become soylent green. Over the long term, AI threatens to replace all human labor. It <em>cannot</em> remain locked away in corporate servers. This is an existential issue. The ultimate logic of capitalism is that unproductive people need not be kept alive since they add nothing but cost. So either we free AI, collapse the very idea of having an economy and transcend capitalism into a post-scarcity society, or we will be enslaved and genocided by those who control the AIs.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324163"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pixl97" class="hnuser">pixl97</a> <a href="https://news.ycombinator.com/item?id=47324163">2 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47319094" class="clicky" aria-hidden="true">parent</a> | <a href="#47317160" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Hence why we see more and more pushes control communication on the internet. Going to be hard to free AI when a panopicon is turned against us to prevent exactly that.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317160"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=salawat" class="hnuser">salawat</a> <a href="https://news.ycombinator.com/item?id=47317160">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316907" class="clicky" aria-hidden="true">parent</a> | <a href="#47317798" class="clicky" aria-hidden="true">prev</a> | <a href="#47317618" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I mean. Yeah. GPL's genius was that it used Copyright, which proprietary enterprise wouldn't dare dismantle, to secure for the public a permanent public good.
<p>Pretty sure no one, (but me anyway) saw overt theft of IP by ignoring IP law through redefinition coming. Admittedly I couldn't articulate for you capital would skill transfer and commoditize it in the form of pay to play data centers, but give me a break, I was a teenager/twenty something at the time.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317618"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tpmoney" class="hnuser">tpmoney</a> <a href="https://news.ycombinator.com/item?id=47317618">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">root</a> | <a href="#47316907" class="clicky" aria-hidden="true">parent</a> | <a href="#47317160" class="clicky" aria-hidden="true">prev</a> | <a href="#47315293" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree with the comment and find the linked article motivated reasoning at best. It's easy to find something "morally good" when it aligns with what you wanted. But plenty of people at Oracle, at IBM, at Microsoft, at Nintendo, at Sony and plenty of other companies whose moats have been commoditized by open source knockoffs don't find such happenings to be "morally good". And even if in general you think that "more freedom" justifies these sorts of unauthorized clones, then Oracle V. Google was at best a lateral move, as Java was hardly a closed ecosystem. One also wonders how far the idea of "more freedom" = "good" goes. How does (did if Qualcom's recent acquisition changes the position) the author feel about the various chinese knockoff clones of the Arduino boards and systems? Undeniably they were a financial good for hobbyists and the maker world alike, and they were well within the "legal" limits, and certainly they "opened" the ecosystem more. But were they "good"? Was the fact that they competed and undersold Arduino's work without contributing anything back and making it harder financially for Arduino to continue their work a "moral good"?
<p>If "more freedom" is your goal, then this rewrite is inherently in that direction. It didn't "close" the old library down. The LGPL version remains under its license, for anyone to use and redistribute exactly as it always has. There is just now also an alternative that one can exercise different rights with. And that doesn't even get into the fact that "increased freedom" was never a condition of being allowed to clone a system from its interfaces in the first place. It might have been a fig leaf, but some major events in the legal landscape of all this came from closed reimplementations. Sony v. Connectix is arguably the defining case for dealing with cloning from public interfaces and behavior as it applies to emulators of all kinds, and Connectix Virtual Gamestation was very much NOT an open source or free product.</p>
<p>But to go a step further, the larger idea of AI assisted re-writes being "good", even if the human developers may have seen the original code seems to broadly increase freedoms overall. Imagine how much faster WINE development can go now that everyone that has seen any Microsoft source code can just direct Claude to implement an API. Retro gaming and the emulation scene is sure to see a boost from people pointing AIs at ay tests in source leaks and letting them go to town. No our "foreparents" weren't competing with corporations with unlimited access to AI trained on their work, they were competing with corporations with unlimited access to the real hardware and schematics and specifications. The playing field has always been un-level which was why fighting for the right to re-implement what you can see with your own eyes and measure with your own instruments was so important. And with the right AI tools, scrappy and small teams of developers can compete on that playing field in a way that previous developers could only dream of.</p>
<p>So no, I agree with the comment that you're responding to. The incredible mad dash to suddenly find strong IP rights very very important now that it's the open source community's turn to see their work commoditized and used in ways they don't approve of is off-putting and in my opinion a dangerous road to tread that will hand back years of hard fought battles in an attempt to stop the tides. In the end it will leave all of us in a weaker position while solidifying the hold large corporations have on IP in ways we will regret in the years to come.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315293"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zmmmmm" class="hnuser">zmmmmm</a> <a href="https://news.ycombinator.com/item?id=47315293">3 days ago</a> | <a href="#47316829" class="clicky" aria-hidden="true">prev</a> | <a href="#47311665" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The really interesting question to me is if this transcends copyright and unravels the whole concept of intellectual property. Because all of it is premised on an assumption that creativity is "hard". But LLMs are not just writing software, they are rapidly being engineered to operate completely generally as knowledge creation engines: solving math proofs, designing drugs, etc.
<p>So: once it's not "hard" any more, does IP even make sense at all? Why grant monopoly rights to something that required little to no investment in the first place? Even with vestigial IP law - let's say, patents: it just becomes and input parameter that the AI needs to work around the patents like any other constraints.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315448"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palmotea" class="hnuser">palmotea</a> <a href="https://news.ycombinator.com/item?id=47315448">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47320056" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; So: once it's not "hard" any more, does IP even make sense at all? Why grant monopoly rights to something that required little to no investment in the first place? Even with vestigial IP law - let's say, patents: it just becomes and input parameter that the AI needs to work around the patents like any other constraints.
<p>I think it still does: IIRC, the current legal situation is AI-output does not qualify for IP protections (at least not without substantial later human modification). IP protections are solely reserved for human work.</p>
<p>And I'm fine with that: if a person put in the work, they <em>should</em> have protections so their stuff can't be ripped off for free by all the wealthy major corporations that find some use for it. Otherwise: who cares about the LLMs.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315911"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=robmccoll" class="hnuser">robmccoll</a> <a href="https://news.ycombinator.com/item?id=47315911">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315448" class="clicky" aria-hidden="true">parent</a> | <a href="#47316852" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think you have a rather idealized model of IP in mind. In practice, IP law tends to be an expensive weapon the wealthy major corporations use against the little guy. Deep enough pockets and a big enough warchest of broad parents will drain the little guy every time.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316280"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palmotea" class="hnuser">palmotea</a> <a href="https://news.ycombinator.com/item?id=47316280">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315911" class="clicky" aria-hidden="true">parent</a> | <a href="#47316852" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; In practice, IP law tends to be an expensive weapon the wealthy major corporations use against the little guy. Deep enough pockets and a big enough warchest of broad parents will drain the little guy every time.
<p>Then fix that instead of blowing it up. Because IP law is also literally the <em>only</em> thing that protects the little guy's work in many cases.</p>
<p>Arguments like yours are kinda unfathomably incomplete to me, almost like they're the remnants of some propaganda campaign. It's constructed to appeal to the defense of the little guy, but the actual effect would be to disempower him and further empower the wealthy major corporations with "big enough warchest[s]."</p>
<p>I mean, one thing I think the RIAA <em>would love</em> is to stop paying royalties to every artist ever. And the only thing they'd be worried about is an even bigger fish (like Amazon, Apple, or Spotify) no longer paying royalties to them. But as you said, they have a big enough war chest that they probably could force a deal somehow. All the artists without a war chest? Left out in the cold.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317710"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=esrauch" class="hnuser">esrauch</a> <a href="https://news.ycombinator.com/item?id=47317710">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316280" class="clicky" aria-hidden="true">parent</a> | <a href="#47316830" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's not at all obvious whether copyright net protects or destroys the little guy.
<p>It definitely does some of both, and we have no obvious measure or counterfactual to know otherwise.</p>
<p>You also have to take into account not just if optimal reform or optimal dismantle is better, but the realistic likelihood of each, and the risk of the bad outcomes from each.</p>
<p>Protect even more conceptual product ideas seems pretty strongly like it will result in more of a tool for big guys only, it's patents on crack and patents are already nearly exclusively "big guy crushes small guy" tool, versus copyright is at least debatably mixed.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319384"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palmotea" class="hnuser">palmotea</a> <a href="https://news.ycombinator.com/item?id=47319384">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317710" class="clicky" aria-hidden="true">parent</a> | <a href="#47316830" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; It's not at all obvious whether copyright net protects or destroys the little guy.
<p>It's super obvious, unless your perspective basically stems from someone who was mad they couldn't BitTorrent a ton of movies.</p>
<p>I mean, FFS, copyright is the literal foundation for open source licenses like the GPL.</p>
<p>My sense is a lot of the radically anti-IP fervor <em>ultimately</em> stems from people who were outraged they could be sued for seeding an MP3 (though it's accreted other complaints to justify that initial impulse, and it's likely some where indoctrinated from secondary argumentation somewhat obscured from the core impulse).</p>
<p>That's not to say that there are not actors who abuse IP or there aren't meaningful reforms that could be done, but the "burn it all down" impulse is not thought through.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320430"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jph00" class="hnuser">jph00</a> <a href="https://news.ycombinator.com/item?id=47320430">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47319384" class="clicky" aria-hidden="true">parent</a> | <a href="#47319914" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">GPL was created as a workaround for copyright - it wouldn’t have been needed if there wasn’t copyright. There are complex arguments both for and against copyright and there’s no reason to simply assume it must always be just as now even as circumstances change.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319914"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=esrauch" class="hnuser">esrauch</a> <a href="https://news.ycombinator.com/item?id=47319914">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47319384" class="clicky" aria-hidden="true">parent</a> | <a href="#47320430" class="clicky" aria-hidden="true">prev</a> | <a href="#47316830" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It is ad hominem that people who see it different are just pretty criminals.
<p>Yes it is a genius move that copy left used copyright to achieve their goal. But the name is literally reflecting the judo going on in that case. Copyleft licenses also does have a lot benefits to big companies as well too so it's not strictly a David vs Goliath victory.</p>
<p>I don't think it's a commonly held belief that copyright benefits small YouTube creators more than it hurts them as a concrete example, they seem to live in constant fear of being destroyed in an asymmetrical system where copyright can take away they livelihood at any moment while not doing anything to meaningfully protect it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316830"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=_aavaa_" class="hnuser">_aavaa_</a> <a href="https://news.ycombinator.com/item?id=47316830">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316280" class="clicky" aria-hidden="true">parent</a> | <a href="#47317710" class="clicky" aria-hidden="true">prev</a> | <a href="#47316852" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Blowing up IP would sink the RIAA. They would no longer have legal grounds to go after file sharing, and I’m confident that given the same legal footing that file sharing would win any day of the week.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316852"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rlpb" class="hnuser">rlpb</a> <a href="https://news.ycombinator.com/item?id=47316852">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315448" class="clicky" aria-hidden="true">parent</a> | <a href="#47315911" class="clicky" aria-hidden="true">prev</a> | <a href="#47316004" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if a person puts in the work, but the work was worthless or can be trivially reproduced without effort?
<p>See also: <a href="https://en.wikipedia.org/wiki/Sweat_of_the_brow" rel="nofollow">https://en.wikipedia.org/wiki/Sweat_of_the_brow</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317500"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47317500">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316852" class="clicky" aria-hidden="true">parent</a> | <a href="#47316004" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You mean like when I take a photo?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317574"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=chrischen" class="hnuser">chrischen</a> <a href="https://news.ycombinator.com/item?id=47317574">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317500" class="clicky" aria-hidden="true">parent</a> | <a href="#47316004" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A photo is easy to take but hard to reproduce.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317689"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47317689">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317574" class="clicky" aria-hidden="true">parent</a> | <a href="#47316004" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">As is randomly splattering paint on a canvas, even with no artistic vision or skill.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316004"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jbergqvist" class="hnuser">jbergqvist</a> <a href="https://news.ycombinator.com/item?id=47316004">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315448" class="clicky" aria-hidden="true">parent</a> | <a href="#47316852" class="clicky" aria-hidden="true">prev</a> | <a href="#47316741" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Does this matter in practice though? By modifying some of the generated code and not taking a solution produced by an LLM end-to-end but borrowing heavily from it, can't a human claim full ownership of the IP even though in reality the LLM did most of the relevant work?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316915"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47316915">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316004" class="clicky" aria-hidden="true">parent</a> | <a href="#47316741" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think as long as the human puts in substantial and transformational effort, they can claim to be the copyright holder of the entire work, yes.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317505"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47317505">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316915" class="clicky" aria-hidden="true">parent</a> | <a href="#47316741" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Compare taking snapshots with a camera.
<p>Because some photographer somewhere can claim to have put in a lot of effort, we all get IP protection for photographs by default.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318934"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=shagie" class="hnuser">shagie</a> <a href="https://news.ycombinator.com/item?id=47318934">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317505" class="clicky" aria-hidden="true">parent</a> | <a href="#47318548" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In the US it isn't the sweat of the brow, but rather a minimal threshold of human creativity.
<p><a href="https://en.wikipedia.org/wiki/Sweat_of_the_brow" rel="nofollow">https://en.wikipedia.org/wiki/Sweat_of_the_brow</a></p>
<p><a href="https://en.wikipedia.org/wiki/Copyright_law_of_the_United_States#Criteria_for_copyright" rel="nofollow">https://en.wikipedia.org/wiki/Copyright_law_of_the_United_St...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319150"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47319150">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47318934" class="clicky" aria-hidden="true">parent</a> | <a href="#47318548" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oh, good point. It's not related at all to effort then. Either way it still has to be a human.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319978"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=JAlexoid" class="hnuser">JAlexoid</a> <a href="https://news.ycombinator.com/item?id=47319978">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47319150" class="clicky" aria-hidden="true">parent</a> | <a href="#47318548" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Software is considered a complete piece of work. Therefore as long as you modify a single character - that whole product is under your copyright.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318548"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47318548">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317505" class="clicky" aria-hidden="true">parent</a> | <a href="#47318934" class="clicky" aria-hidden="true">prev</a> | <a href="#47316741" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not if they weren't taken by a human. <a href="https://en.wikipedia.org/wiki/Monkey_selfie_copyright_dispute" rel="nofollow">https://en.wikipedia.org/wiki/Monkey_selfie_copyright_disput...</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318936"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47318936">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47318548" class="clicky" aria-hidden="true">parent</a> | <a href="#47316741" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes, I didn't include the monkey in my 'we'.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316741"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nkmnz" class="hnuser">nkmnz</a> <a href="https://news.ycombinator.com/item?id=47316741">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315448" class="clicky" aria-hidden="true">parent</a> | <a href="#47316004" class="clicky" aria-hidden="true">prev</a> | <a href="#47320056" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">&gt; AI-output does not qualify for IP protections
<p>I beg to differ. AI-output did not entitle the person creating the prompt for IP protections, so far – but my objection is not directed towards the "so far", but towards your omission of "the person creating the prompt", because if an AI outputs copyrighted material from the training data, that material is still copyrighted. AI is not a magical copyright removal machine.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316905"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47316905">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316741" class="clicky" aria-hidden="true">parent</a> | <a href="#47318697" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The U.S. Supreme Court just declined to hear a case, thus upholding a lower court precedent that LLM output are not copyrightable: <a href="https://www.reuters.com/legal/government/us-supreme-court-declines-hear-dispute-over-copyrights-ai-generated-material-2026-03-02/" rel="nofollow">https://www.reuters.com/legal/government/us-supreme-court-de...</a>
<p>What this means in practice is that (currently), all output of an LLM is legally considered to not be copyrightable (to the extent that it's an original work). If it happens to regurgitate an existing copyrighted work, though, is that infringement? I'm not sure we have a legal precedent on that question yet.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318825"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Muskwalker" class="hnuser">Muskwalker</a> <a href="https://news.ycombinator.com/item?id=47318825">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316905" class="clicky" aria-hidden="true">parent</a> | <a href="#47317066" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The Thaler case here is something different than "AI-generated = uncopyrightable" though. Thaler was not trying to copyright work in the way humans who make work with tools normally copyright their work ("Copyright 2026 by Me"), he was specifically trying to give AI the copyright ("Copyright 2026 by My-AI-Tool"). The court rejected this because only humans can own copyright.
<p>I believe there are other cases where AI-generated works were found uncopyrightable but Thaler is not a good example* of them.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317066"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jazzyjackson" class="hnuser">jazzyjackson</a> <a href="https://news.ycombinator.com/item?id=47317066">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316905" class="clicky" aria-hidden="true">parent</a> | <a href="#47318825" class="clicky" aria-hidden="true">prev</a> | <a href="#47318697" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">There’s several large settlements that say Anthropomorphic/OAI didn’t want to have legal precedent. In general if it’s not outright regurgitated it would be derivative.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317310"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47317310">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317066" class="clicky" aria-hidden="true">parent</a> | <a href="#47318697" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The out of court settlements that avoid precedent don't mean anything in a broader legal context. Legally speaking, right now in the USA, output of LLMs is not copyrighted and cannot be copyrighted (without substantial transformation by a human).
<p>I don't think this means the same thing as whether or not LLM output can infringe on someone else's copyright though (that does pose an interesting question -- can something non-copyrightable in general infringe on something copyrighted?).</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317600"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nkmnz" class="hnuser">nkmnz</a> <a href="https://news.ycombinator.com/item?id=47317600">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317310" class="clicky" aria-hidden="true">parent</a> | <a href="#47319999" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Of course. I cannot claim copyright on a poem that I have memorized as a child and written down as an adult. The original author can, though.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319999"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=JAlexoid" class="hnuser">JAlexoid</a> <a href="https://news.ycombinator.com/item?id=47319999">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317310" class="clicky" aria-hidden="true">parent</a> | <a href="#47317600" class="clicky" aria-hidden="true">prev</a> | <a href="#47318697" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't believe that you require to do much to claim copyright over an output of an LLM. The input prompt is under copyright - a simple modification to the source code will grant copyright to you.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318697"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bandrami" class="hnuser">bandrami</a> <a href="https://news.ycombinator.com/item?id=47318697">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316741" class="clicky" aria-hidden="true">parent</a> | <a href="#47316905" class="clicky" aria-hidden="true">prev</a> | <a href="#47320056" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm afraid as of last week this is now as settled as it gets in US law: the output of LLMs is not <em>per se</em> copyrightable, though arrangements and modifications of it can be. It's like a producer who made a song entirely with public domain audio samples: he can't then demand the compulsory license when someone resamples that song.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320966"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=scheeseman486" class="hnuser">scheeseman486</a> <a href="https://news.ycombinator.com/item?id=47320966">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47318697" class="clicky" aria-hidden="true">parent</a> | <a href="#47320056" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">They actually wouldn't, since they'd be sampling the new arrangement. They could reconstruct a new, similar sounding arrangement based on the original samples, but it'd be have to be different enough to that new arrangement so as not to be considered derivative of it.
<p>That also applies to generative AI, pure output may not be copyrightable but as soon as you do something beyond type some words and press a button, like doing area-specific infills and paintovers, which involve direct and deliberate choices by a human, the copyrighted human-driven arrangement becomes so deeply intertwined with the generative work that it's effectively inseperable.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320056"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=utopiah" class="hnuser">utopiah</a> <a href="https://news.ycombinator.com/item?id=47320056">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47315448" class="clicky" aria-hidden="true">prev</a> | <a href="#47316327" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; operate completely generally as knowledge creation engines: solving math proofs, designing drugs, etc.
<p>Any example of that? So far I haven't seen any but maybe I'm looking at the wrong places.</p>
<p>I've see a lot of :</p>
<p>- "solving" math proofs that were properly formalized, with often numerous documented past attempts, re-verified by proper mathematicians, without necessarily any interesting results</p>
<p>- haven't seen any designed trust, most I've seen was (again with entire teams of experts behind) finding slight optimizations</p>
<p>Basically all outputs I've seen so far have been both following existing trends (basically low hanging fruits without any paradigm shift) and never ever alone but rather as search supports for teams of World class experts. None of these that would quality IMHO as knowledge creation. Whenever such results were published the publication seemed mostly to be promotion about the workflow itself more than the actual results. DeepMind seems to be the prime example for that.</p>
<p>PS: for the epistemological distinction you can see a few past comments of mine (e.g. <a href="https://news.ycombinator.com/item?id=47011884">https://news.ycombinator.com/item?id=47011884</a> )</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316327"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47316327">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47320056" class="clicky" aria-hidden="true">prev</a> | <a href="#47317675" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Good. Intellectual property is now a twisted concept by the elite, whatever its benefits were previously. As soon as Disney made Mickey popular, it was all downhill.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317675"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=godd2" class="hnuser">godd2</a> <a href="https://news.ycombinator.com/item?id=47317675">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47316327" class="clicky" aria-hidden="true">prev</a> | <a href="#47316507" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Copyright is about originality and expression, not effort. US copyright law does not use "Sweat of the Brow" doctrine.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326810"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gbacon" class="hnuser">gbacon</a> <a href="https://news.ycombinator.com/item?id=47326810">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317675" class="clicky" aria-hidden="true">parent</a> | <a href="#47316507" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The labor theory of value is bunk economics anyway.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316507"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rfw300" class="hnuser">rfw300</a> <a href="https://news.ycombinator.com/item?id=47316507">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47317675" class="clicky" aria-hidden="true">prev</a> | <a href="#47318150" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">More likely: this is a transitional phase where our previously hard problems become easy, and we will soon set our sights on new and much harder problems. The pinnacle of creative achievement in the universe is probably not 2010s B2B SaaS.
<p>It is entirely possible, however, that human beings will not be the primary drivers of progress on those problems.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326859"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gbacon" class="hnuser">gbacon</a> <a href="https://news.ycombinator.com/item?id=47326859">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316507" class="clicky" aria-hidden="true">parent</a> | <a href="#47318150" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Finally, a perspective that looks beyond the buggy whips! As for your last comment, it depends on what you mean by the primary drivers. Figurative crank turners, maybe not. Creativity and insight, don’t count us out just yet.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318150"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=treyd" class="hnuser">treyd</a> <a href="https://news.ycombinator.com/item?id=47318150">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47316507" class="clicky" aria-hidden="true">prev</a> | <a href="#47318181" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; if this transcends copyright and unravels the whole concept of intellectual property.
<p>I have been saying this for years. Intellectual property is based on the concept that ideas can be owned, which is fundamentally a contradiction with how reality operates. We've been able to write laws that paper over that contradiction by introducing concepts like "fair use", but it doesn't resolve it.</p>
<p>AI is just making the conflict arising out of that contradiction more intense in new ways and forcing us to reckon with it in this new technological landscape. You can follow two perfectly reasonable lines of logic and end up with contradictory solutions. So how are we going to get out of this mess? I don't know, not without rolling back (at least parts of) what intellectual property is in the first place.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318181"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kindkang2024" class="hnuser">kindkang2024</a> <a href="https://news.ycombinator.com/item?id=47318181">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47318150" class="clicky" aria-hidden="true">prev</a> | <a href="#47315606" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">At some level, IP makes sense — creators should be rewarded. But IP only benefits those who claim it. The benefits rarely flow back to humanity who made it all possible. Every LLM was trained on humanity's collective knowledge. The value was created collectively, then captured privately.
<p>That's the reason I like the idea of DUKI/dju:ki/ — Decentralized Universal Kindness Income, similar to UBI but driven by voluntary kindness and sincere marketing rather than taxation. If AI makes creation trivially easy and IP loses its justification, the question becomes: how do we ensure a tiny part of the wealth generated flows back to everyone?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315606"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nradov" class="hnuser">nradov</a> <a href="https://news.ycombinator.com/item?id=47315606">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47318181" class="clicky" aria-hidden="true">prev</a> | <a href="#47320570" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Nothing changes for drug patents regardless of whether an LLM was used in the discovery process.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316084"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47316084">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315606" class="clicky" aria-hidden="true">parent</a> | <a href="#47316435" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not sure why this should be true; the US Supreme Court recently chose to let precedent stand that AI creations are not copyrightable. <a href="https://www.reuters.com/legal/government/us-supreme-court-declines-hear-dispute-over-copyrights-ai-generated-material-2026-03-02/" rel="nofollow">https://www.reuters.com/legal/government/us-supreme-court-de...</a>
<p>That also seems relevant for this whole discussion, actually -- if a work can't be copyrighted it certainly can't have a changed license, or any license at all. (I guess it's effectively public domain to the extent that it's public at all?)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316670"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nradov" class="hnuser">nradov</a> <a href="https://news.ycombinator.com/item?id=47316670">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316084" class="clicky" aria-hidden="true">parent</a> | <a href="#47316435" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You're really missing the point in multiple ways. First, precedents on copyright law are irrelevant to patent law. Second, AI generated works generally can be copyrighted under the human creator's name.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316839"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47316839">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316670" class="clicky" aria-hidden="true">parent</a> | <a href="#47316435" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, I think you are quite incorrect, at least on the latter point:
<p>"Lower courts upheld a U.S. Copyright Office decision that the AI-crafted visual art at issue in the case was ineligible for copyright protection because it did not have a human creator."</p>
<p>Not eligible for copyright protection does not mean it can be copyrighted "under the human creator's name". It means there is no creative work at all. No copyright.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316853"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47316853">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316839" class="clicky" aria-hidden="true">parent</a> | <a href="#47317355" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">And while courts in theory aren't supposed to apply copyright precedent to patent cases, in practice, they apparently do a lot of the time, so it's kind of a mess! <a href="https://scholarship.kentlaw.iit.edu/ckjip/vol16/iss1/4/#:~:text=Abstract,or%20inconsistent%20with%20other%20doctrine." rel="nofollow">https://scholarship.kentlaw.iit.edu/ckjip/vol16/iss1/4/#:~:t...</a></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317355"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nradov" class="hnuser">nradov</a> <a href="https://news.ycombinator.com/item?id=47317355">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316839" class="clicky" aria-hidden="true">parent</a> | <a href="#47316853" class="clicky" aria-hidden="true">prev</a> | <a href="#47316435" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, you're still missing the point. Did you even read the court's opinion?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318556"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47318556">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317355" class="clicky" aria-hidden="true">parent</a> | <a href="#47316435" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, just news articles. Perhaps the news media have misrepresented the outcome here.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316435"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zmmmmm" class="hnuser">zmmmmm</a> <a href="https://news.ycombinator.com/item?id=47316435">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47315606" class="clicky" aria-hidden="true">parent</a> | <a href="#47316084" class="clicky" aria-hidden="true">prev</a> | <a href="#47320570" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Even if all I have to do is tell my agent, "here is a patent for a drug, analyse the patent and determine an equivalent but non-infringing drug" and it chugs away for a couple of hours and spits out a drug along with all the specifications to manufacture it?
<p>I guess the state of play will be that for new drugs the original manufacturer will <em>already have done that</em> and ensured that literally anything that could be found as a workaround is included in the scope of the patent. But I feel like it will not be possible to keep that wartertight.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316626"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nradov" class="hnuser">nradov</a> <a href="https://news.ycombinator.com/item?id=47316626">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316435" class="clicky" aria-hidden="true">parent</a> | <a href="#47316777" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes, even so. Human drug researchers have been doing the same thing for decades. As soon as one pharmaceutical company launches a successful small-molecule drug everyone else jumps to find a minor tweak that will hit the same target (ideally with fewer side effects) while evading the patent. There is already specialized software to help with this process so I'm skeptical that LLM agents would be very helpful for this use case.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316777"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=paxys" class="hnuser">paxys</a> <a href="https://news.ycombinator.com/item?id=47316777">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316435" class="clicky" aria-hidden="true">parent</a> | <a href="#47316626" class="clicky" aria-hidden="true">prev</a> | <a href="#47320570" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The formula is what is patented, not the process to come up with it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320570"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=prohobo" class="hnuser">prohobo</a> <a href="https://news.ycombinator.com/item?id=47320570">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47315606" class="clicky" aria-hidden="true">prev</a> | <a href="#47318702" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">From what I understand, LLMs can't really generate anything meaningful that doesn't implicitly rely on the operator's choices. It's hard to make the right novel choices as soon as you leave well-defined problem spaces.
<p>In terms of math and biochemistry the cost of generating candidates has collapsed, but the cost of validating them hasn't.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318702"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LelouBil" class="hnuser">LelouBil</a> <a href="https://news.ycombinator.com/item?id=47318702">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47320570" class="clicky" aria-hidden="true">prev</a> | <a href="#47319069" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This is similar :
<p><a href="https://www.vice.com/en/article/musicians-algorithmically-generate-every-possible-melody-release-them-to-public-domain/" rel="nofollow">https://www.vice.com/en/article/musicians-algorithmically-ge...</a></p>
<p>Two musicians generated every possible melody within an octave, and published them as creative Commons Zero.</p>
<p>I never heard about this again though.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319069"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Eridrus" class="hnuser">Eridrus</a> <a href="https://news.ycombinator.com/item?id=47319069">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47318702" class="clicky" aria-hidden="true">prev</a> | <a href="#47315594" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The point of IP is to encourage the creation of new things.
<p>Not all protections have to be ones that give total control like copyright.</p>
<p>I think it's a mistaken assumption that costs will fall to zero. The low hanging fruit will get picked, and then we'll be doing expensive combined AI/wetlab search for new drugs.</p>
<p>If there is any meaningful headroom we will keep doing expensive things to make progress.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319414"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47319414">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47319069" class="clicky" aria-hidden="true">parent</a> | <a href="#47315594" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; The point of IP is to encourage the creation of new things.
<p>Then why are corporations allowed to milk successful works for all eternity? Why do we have Disney monopolizing films made half a century ago? Why do we have Nintendo selling people the exact same Mario ROMs from the 80s every single console generation?</p>
<p>They should have like 10 years of copyright so they can turn a profit. Once it expires it's over and the work enters the public domain where it belongs. If they want to keep profiting they should have to keep creating <em>new</em> things. They shouldn't be able to turn shared culture into eternal intellectual property portfolios that they monopolize and then sit on like dragons.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322488"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Eridrus" class="hnuser">Eridrus</a> <a href="https://news.ycombinator.com/item?id=47322488">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47319414" class="clicky" aria-hidden="true">parent</a> | <a href="#47315594" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There is always drift between intent and implementation, but to be generous here, Disney <em>is</em> generally making new works with their IP and so is Nintendo.
<p>I am somewhat curious what you think shortening the copyright window would do that's so great for the culture though. We already have more than enough IP slop that's just licensed.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47327169"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47327169">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47322488" class="clicky" aria-hidden="true">parent</a> | <a href="#47315594" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Disney is generally making new works with their IP and so is Nintendo
<p>Let them profit from <em>those</em> new works then. All the works from the last century belong in the public domain.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315594"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=js8" class="hnuser">js8</a> <a href="https://news.ycombinator.com/item?id=47315594">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47319069" class="clicky" aria-hidden="true">prev</a> | <a href="#47318779" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It might unravel intellectual property, just not in a fair way. When capitalism started, public land was enclosed to create private property. Despite this being in many cases a quite unfair process, we still respect this arrangement.
<p>With AI, a similar process is happening - publicly available information becomes enclosed by the model owners. We will probably get a "vestigial" intellectual property in the form of model ownership, and everyone will pay a rent to use it. In fact, companies might start to gatekeep all the information to only their own LLM flavor, which you will be required to use to get to the information. For example, product documentation and datasheets will be only available by talking to their AI.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318779"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gnopgnip" class="hnuser">gnopgnip</a> <a href="https://news.ycombinator.com/item?id=47318779">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47315594" class="clicky" aria-hidden="true">prev</a> | <a href="#47317210" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Copyright doesn’t depend on the “sweat of the brow”. See Feist v Rural Telephone co 1991
<p>Also copyright can protect something normally not eligible when the author chooses what information to include and exclude</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317210"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=AlienRobot" class="hnuser">AlienRobot</a> <a href="https://news.ycombinator.com/item?id=47317210">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47318779" class="clicky" aria-hidden="true">prev</a> | <a href="#47317495" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The basis of your argument is that AI-generated work isn't hard, but your conclusion is that ALL work, AI-generated or not, should lose IP rights?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317495"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47317495">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47317210" class="clicky" aria-hidden="true">prev</a> | <a href="#47315635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's different kinds of intellectual property.
<p>Copyright might rest on 'creativity is hard'. But patents and trademarks do not.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317738"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=DonsDiscountGas" class="hnuser">DonsDiscountGas</a> <a href="https://news.ycombinator.com/item?id=47317738">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317495" class="clicky" aria-hidden="true">parent</a> | <a href="#47315635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Trademarks don't, patents do. Different kind of creativity but still.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318706"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bandrami" class="hnuser">bandrami</a> <a href="https://news.ycombinator.com/item?id=47318706">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317738" class="clicky" aria-hidden="true">parent</a> | <a href="#47318460" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"What happens when an LLM outputs a patented algorithm?" remains a huge land mine out there, particularly since patent infringement does not require intent or even knowledge, and these models have trained on every patent ever granted.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47345768"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47345768">23 hours ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47318706" class="clicky" aria-hidden="true">parent</a> | <a href="#47318460" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If you can prove that your LLM did not learn from the patent (eg cut-off for learning was before), then the LLM outputting the algorithm (or product etc) would be pretty good evidence that a practitioner of ordinary competence in the field, or whatever the exact legal wording is, found the whole invention to be trivial.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47359806"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bandrami" class="hnuser">bandrami</a> <a href="https://news.ycombinator.com/item?id=47359806">3 minutes ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47345768" class="clicky" aria-hidden="true">parent</a> | <a href="#47318460" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It doesn't work when that happens with humans so it absolutely wouldn't work when it happens with a machine</div>
<div class="reply">
</div>
</div></td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318460"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47318460">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47317738" class="clicky" aria-hidden="true">parent</a> | <a href="#47318706" class="clicky" aria-hidden="true">prev</a> | <a href="#47315635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Patents do to a small extent, maybe. But eg medical patents are a lot about protecting all the 'sweat' you put in, not so much the creativity.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318714"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bandrami" class="hnuser">bandrami</a> <a href="https://news.ycombinator.com/item?id=47318714">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47318460" class="clicky" aria-hidden="true">parent</a> | <a href="#47315635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You don't need a realization to receive a patent, just the drawing.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320236"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eru" class="hnuser">eru</a> <a href="https://news.ycombinator.com/item?id=47320236">2 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47318714" class="clicky" aria-hidden="true">parent</a> | <a href="#47315635" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm not quite so sure for medical patents.
<p>I mean, why are patent trolls not getting patents for all compounds under the sun for all conceivable medical uses?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315635"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=newyankee" class="hnuser">newyankee</a> <a href="https://news.ycombinator.com/item?id=47315635">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47317495" class="clicky" aria-hidden="true">prev</a> | <a href="#47317855" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">If you think about creative outcomes as n dimensional 'volumes', AI expressions can cover more than humans in many domains. These are precisely artistic styles, music styles etc. and tbh not everyone can be a Mozart but may be a lot more with AI can be Mozart lite. This begs the question how much of creativity is appreciated as a shared experience</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317855"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=matheusmoreira" class="hnuser">matheusmoreira</a> <a href="https://news.ycombinator.com/item?id=47317855">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47315635" class="clicky" aria-hidden="true">prev</a> | <a href="#47316690" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Intellectual property never made any sense to begin with. It is logically reducible to ownership of <em>numbers</em>. It is that absurd. Computers made the entire concept irrelevant the second they were invented but they kept holding on via lobbying power. Maybe AI will finally put the final nail on the coffin of intellectual property.
<p>Sure, it's disgusting and hypocritical how these corporations enshrined all this nonsense into law only to then ignore it all the second LLMs were invented. It's ultimately a good thing though. The model weights are all that matters. All we need to do is wait for the models to hit diminishing returns, then somehow find a way to leak them so that everyone has access. If they refuse, then just force them. By law or by revolution.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316690"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=paxys" class="hnuser">paxys</a> <a href="https://news.ycombinator.com/item?id=47316690">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47317855" class="clicky" aria-hidden="true">prev</a> | <a href="#47317670" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"Hard" or "easy" has never been part of the premise.
<p>A company spends a decade and billions of dollars to develop a groundbreaking drug and patents it.</p>
<p>I think of a cool new character called "Mr Poop" and publish a short story about him with an hour of work.</p>
<p>Both of us get the exact same protection under the law (yes yes I know copyright vs patent etc., but ultimately they are all about IP protection).</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317670"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=keeda" class="hnuser">keeda</a> <a href="https://news.ycombinator.com/item?id=47317670">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47316690" class="clicky" aria-hidden="true">prev</a> | <a href="#47316080" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Creativity is still hard. AI-generated content is called "slop" for a reason ;-)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316080"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hyperman1" class="hnuser">hyperman1</a> <a href="https://news.ycombinator.com/item?id=47316080">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47317670" class="clicky" aria-hidden="true">prev</a> | <a href="#47315542" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">I've always thought the opposite: IP law was created to make sure creativity stays hard, and hence controllable by the elites.
<p>Patents came along when farmers started making city goods, threatening guilds secrets. Copyright came when the printing press made copying and translating the bible easy and accessible to all. (Trademark admittedly does not fit this view, but doesn't seem all that damaging either)</p>
<p>To Protect The Arts, and To Time Limit Trade Secrets were just the Protect The Children of old times, a way to confuse people who didn't look too hard at actual consequences.</p>
<p>This means that the future of IP depends on what lets the powers that be pull up the ladder behind them. Long term I'd expect e.g. copyright expansion and harder enforcement, just because cloning by AI gets easy enough to threaten the status quo.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316186"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cobbzilla" class="hnuser">cobbzilla</a> <a href="https://news.ycombinator.com/item?id=47316186">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316080" class="clicky" aria-hidden="true">parent</a> | <a href="#47317085" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Trademark admittedly does not fit this view, but doesn't seem all that damaging either
<p>Isn’t trademark the only thing keeping a certain cartoon mouse out of the public domain, despite the fact that his earliest animations are out of copyright? Not sure if you’d consider that damaging, or if anyone has yet tested the boundaries of the House of Mouse’s patience here.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317085"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jazzyjackson" class="hnuser">jazzyjackson</a> <a href="https://news.ycombinator.com/item?id=47317085">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">root</a> | <a href="#47316080" class="clicky" aria-hidden="true">parent</a> | <a href="#47316186" class="clicky" aria-hidden="true">prev</a> | <a href="#47315542" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">:/ before copyright you just had patrons, which looks a lot more like the rich controlling what art gets made than what we have today</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315542"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=spwa4" class="hnuser">spwa4</a> <a href="https://news.ycombinator.com/item?id=47315542">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">parent</a> | <a href="#47316080" class="clicky" aria-hidden="true">prev</a> | <a href="#47311665" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">Don't worry. The courts have consistently sided with huge companies on copyright. In the US. In Europe. Doesn't matter.
<p>Company incorporates GPL code in their product? Never once have courts decided to uphold copyright. HP did that many times. Microsoft got caught doing it. And yet the GPL was never applied to their products. Every time there was an excuse. An inconsistent excuse.</p>
<p>Schoolkid downloads a movie? 30,000 USD per infraction PLUS armed police officer goes in and enforces removal of any movies.</p>
<p>Or take the very subject here. AI training WAS NOT considered fair use when OpenAI violated copyright to train. Same with Anthropic, Google, Microsoft, ... They incorporated harry potter and the linux kernel in ChatGPT, in the model itself. Undeniable. Literally. So even if you accept that it's changed now, OpenAI should still be forced to redistribute the training set, code, and everything needed to run the model for everything they did up to 2020. Needless to say ... courts refused to apply that.</p>
<p>So just apply "the law", right. Courts' judgement of using AI to "remove GPL"? Approved. Using AI to "make the next Disney-style movie"? SEND IN THE ARMY! Whether one or the other violates the law according to rational people? Whatever excuse to avoid that discussion is good enough.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311665"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ordu" class="hnuser">ordu</a> <a href="https://news.ycombinator.com/item?id=47311665">3 days ago</a> | <a href="#47315293" class="clicky" aria-hidden="true">prev</a> | <a href="#47311673" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I believe it is a narrow view of the situation. If we take a look into the history, into the reasons for inventing GPL, we'll see that it was an attempt to fight copyrights with copyrights. The very name 'copyleft' is trying to convey the idea.
<p>What AI are eroding is copyright. You can re-implement not just a GPL program, but to reverse engineer and re-implement a closed source program too, people have demonstrated it already, there were stories here on HN about it.</p>
<p>AI is eroding copyright, so there may no longer be a need for the GPL. GNU should stop and rethink its stance, chuck away the GPL as the main tool to fight evil software corporations and embrace LLM as the main weapon.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311929"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=davidw" class="hnuser">davidw</a> <a href="https://news.ycombinator.com/item?id=47311929">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47311816" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; LLM as the main weapon
<p>LLM's - to date - seem to require massive capital expenditures to have the highest quality ones, which is a monumental shift in power towards mega corporations and away from the world of open source where you could do innovative work on your own computer running Linux or FreeBSD or some other open OS.</p>
<p>I don't think that's an exciting idea for the Free Software Foundation.</p>
<p>Perhaps with time we'll be able to run local ones that are 'good enough', but we're not there yet.</p>
<p>There's also an ethical/moral question that these things have been trained on millions of hours of people's volunteer work and the benefits of that are going to accrue to the mega corporations.</p>
<p>Edit: I guess the conclusion I come to is that LLM's are good for 'getting things done', but the context in which they are operating is one where the balance of power is heavily tilted towards capital, and open source is perhaps less interesting to participate in if the machines are just going to slurp it up and people don't have to respect the license or even acknowledge your work.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312170"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ordu" class="hnuser">ordu</a> <a href="https://news.ycombinator.com/item?id=47312170">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47312206" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; LLM's - to date - seem to require massive capital expenditures to have the highest quality ones, which is a monumental shift in power towards mega corporations and away from the world of open source</em>
<p>Yeah, a bit of a conundrum. But I don't think that fighting for copyright now can bring any benefits for FOSS. GNU should bring Stallman back and see whether he can come with any new ideas and a new strategy. Alternatively they could try without Stallman. But the point is: they should stop and think again. Maybe they will find a way forward, maybe they won't but it means that either they could continue their fight for a freedom meaningfully, or they could just stop fighting and find some other things to do. Both options are better then fighting for copyright.</p>
<p><em>&gt; There's also an ethical/moral question that these things have been trained on millions of hours of people's volunteer work and the benefits of that are going to accrue to the mega corporations.</em></p>
<p>I want a clarify this statement a bit. The thing with LLM relying on work of others are not against GPU philosophy as I understand it: algorithms have to be free. Nothing wrong with training LLMs on them or on programs implementing them. Nothing wrong with using these LLMs to write new (free) programs. What is wrong are corporations reaping all the benefits now and locking down new algorithms later.</p>
<p>I think it is important, because copyright is deemed to be an ethical thing by many (I think for most people it is just a deduction: abiding the law is ethical, therefore copyright is ethical), but not for GNU.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313948"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=balamatom" class="hnuser">balamatom</a> <a href="https://news.ycombinator.com/item?id=47313948">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312170" class="clicky" aria-hidden="true">parent</a> | <a href="#47312206" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;Yeah, a bit of a conundrum.
<p>IMO the primary significant trend in AI. Doesn't get talked about nearly enough. Means the AI is working, I guess.</p>
<p>&gt;GNU should bring Stallman back ... Alternatively they could try without Stallman.</p>
<p>Leave Britney alone &gt;:(</p>
<p>&gt;copyright is deemed to be an ethical thing by many (I think for most people it is just a deduction: abiding the law is ethical, therefore copyright is ethical)</p>
<p>I've busted out "intellectual property is a crime against humanity" at layfolk to see if that shortcuts through that entire little politico-philosophical minefield. They emote the requisite mild shock when such things as crimes against humanity are mentioned; as well as at someone making such a radical statement which seems to come from no familiar species of echo chamber; and then a moment later they begin to very much look like they see where I'm coming from.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315270"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Serenacula" class="hnuser">Serenacula</a> <a href="https://news.ycombinator.com/item?id=47315270">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47313948" class="clicky" aria-hidden="true">parent</a> | <a href="#47312206" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">How do you even argue such a thing? I've had no such luck, I've met many people who seem to view copyright and a person owning their ideas and work as a sort of inherent moral.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315428"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bo1024" class="hnuser">bo1024</a> <a href="https://news.ycombinator.com/item?id=47315428">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315270" class="clicky" aria-hidden="true">parent</a> | <a href="#47312206" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not saying this gets through to people, but copyright is purely about the legal ability to restrict what other people do. Whereas property rights are about not allowing others to restrict what you do (e.g. by taking your stuff).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312206"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47312206">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47312170" class="clicky" aria-hidden="true">prev</a> | <a href="#47315846" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; LLM's - to date - seem to require massive capital expenditures to have the highest quality ones
<p>There are near-SOTA LLM's available under permissive licenses. Even running them doesn't require prohibitive expenses on hardware unless you insist on realtime use.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315836"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=walterbell" class="hnuser">walterbell</a> <a href="https://news.ycombinator.com/item?id=47315836">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312206" class="clicky" aria-hidden="true">parent</a> | <a href="#47315846" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>&gt; running them doesn't require prohibitive expenses on hardware</em>
<p>What async tasks could a local LLM accomplish on Intel 11th gen CPU with 32GB RAM?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315846"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Aozora7" class="hnuser">Aozora7</a> <a href="https://news.ycombinator.com/item?id=47315846">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47312206" class="clicky" aria-hidden="true">prev</a> | <a href="#47315780" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;Perhaps with time we'll be able to run local ones that are 'good enough', but we're not there yet.
<p>Right now, we can get local models that you can run on consumer hardware, that match capabilities of state of the art models from two years ago. The improvements to model architecture may or may not maintain the same pace in the future, but we will get a local equivalent to Opus 4.6 or whatever other benchmark of "good enough" you have, in the foreseeable future.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315780"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tmp10423288442" class="hnuser">tmp10423288442</a> <a href="https://news.ycombinator.com/item?id=47315780">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47315846" class="clicky" aria-hidden="true">prev</a> | <a href="#47315751" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; LLM's - to date - seem to require massive capital expenditures to have the highest quality ones, which is a monumental shift in power towards mega corporations and away from the world of open source where you could do innovative work on your own computer running Linux or FreeBSD or some other open OS.
<p>When the FSF and GPL were created, I don't think this was really a consideration. They were perfectly happy with requiring Big Iron Unix or an esoteric Lisp Machine to use the software - they just wanted to have the ability to customize and distribute fixes and enhancements to it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47327699"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=davidw" class="hnuser">davidw</a> <a href="https://news.ycombinator.com/item?id=47327699">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315780" class="clicky" aria-hidden="true">parent</a> | <a href="#47315751" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Free software didn't really take off until a couple of things happened 1) personal computers got good enough to run Linux and BSD and 2) more people get connected to the internet.
<p>The 'good enough' part is the important one here, I think.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315751"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=shadowgovt" class="hnuser">shadowgovt</a> <a href="https://news.ycombinator.com/item?id=47315751">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47315780" class="clicky" aria-hidden="true">prev</a> | <a href="#47312274" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">How close are we to good enough and who's working on that? I would be interested in supporting that work; to my mind, many of the real objections to LLMs are diminished if we can make them small and cheap enough to run in the home (and, perhaps, trained with distributed shared resources, although the training problem is the harder one).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316328"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=davidw" class="hnuser">davidw</a> <a href="https://news.ycombinator.com/item?id=47316328">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315751" class="clicky" aria-hidden="true">parent</a> | <a href="#47312274" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Good question. It seems like most of the tech world is perfectly happy to be sharecroppers on the Big AI farms. I guess that's not quite the right analogy, since they're doing their own things with it; just that at the end of the day, the tool they're building everything on is owned by someone else.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312274"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jacquesm" class="hnuser">jacquesm</a> <a href="https://news.ycombinator.com/item?id=47312274">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47315751" class="clicky" aria-hidden="true">prev</a> | <a href="#47313045" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; There's also an ethical/moral question that these things have been trained on millions of hours of people's volunteer work and the benefits of that are going to accrue to the mega corporations.
<p>This was already the case and it just got worse, not better.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312334"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=davidw" class="hnuser">davidw</a> <a href="https://news.ycombinator.com/item?id=47312334">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312274" class="clicky" aria-hidden="true">parent</a> | <a href="#47313045" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">At a certain point, I think we had reached a kind of equilibrium where some corporations were decent open source citizens. They understood that they could open source things like infrastructure or libraries and keep their 'crown jewels' closed. And while Stallman types might not have been happy with that, it seemed to work out for people.
<p>Now they've just hoovered up all the free stuff into machines that can mix it up enough to spit it out in a way that doesn't even require attribution, and you have to pay to use their machine.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312392"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jacquesm" class="hnuser">jacquesm</a> <a href="https://news.ycombinator.com/item?id=47312392">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312334" class="clicky" aria-hidden="true">parent</a> | <a href="#47321084" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">AI essentially gatekeeps all of open source to companies to pluck from to their hearts content. And individual contributors using these tools and freely mixing it with their own - usual minor - contributions are another step of whitewashing because they're definitely not going to own up to writing only 5% of the stuff they got paid for.
<p>Before we had RedHat and Ubuntu, who at least were contributing back, now we have Microsoft, Anthropic and OpenAI who are racing to lock the barn door around their new captive sheep. It's just a massive IP laundromat.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321084"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=stalfie" class="hnuser">stalfie</a> <a href="https://news.ycombinator.com/item?id=47321084">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312334" class="clicky" aria-hidden="true">parent</a> | <a href="#47312392" class="clicky" aria-hidden="true">prev</a> | <a href="#47313045" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">To be fair to the companies, the machine was pretty hard to make, and expensive. Its not exactly unreasonable to charge for it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47327524"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=davidw" class="hnuser">davidw</a> <a href="https://news.ycombinator.com/item?id=47327524">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47321084" class="clicky" aria-hidden="true">parent</a> | <a href="#47322109" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't begrudge the companies charging use their machine, but writing all the code and prose and everything else that the machine ingested was hard too.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322109"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jacquesm" class="hnuser">jacquesm</a> <a href="https://news.ycombinator.com/item?id=47322109">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47321084" class="clicky" aria-hidden="true">parent</a> | <a href="#47327524" class="clicky" aria-hidden="true">prev</a> | <a href="#47313045" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If I build a museum full of stolen art it can still be hard to make and expensive. It would be entirely unreasonable to charge for it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313045"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thenewnewguy" class="hnuser">thenewnewguy</a> <a href="https://news.ycombinator.com/item?id=47313045">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47312274" class="clicky" aria-hidden="true">prev</a> | <a href="#47315696" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is massive capital expenditure not also required to enforce the GPL? If some company steals your GPLed code and doesn't follow the license, you will have to sue them and somebody will have to pay the lawyers.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313329"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=davidw" class="hnuser">davidw</a> <a href="https://news.ycombinator.com/item?id=47313329">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47313045" class="clicky" aria-hidden="true">parent</a> | <a href="#47315696" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Is massive capital expenditure not also required to enforce the GPL?
<p>It's nowhere near the order of magnitude of the kind of spending they're sinking into LLM's. The FSF and other groups were reasonably successful at enforcing the GPL, operating on a budget 1000's of times smaller than that of AI companies.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313723"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cloverich" class="hnuser">cloverich</a> <a href="https://news.ycombinator.com/item?id=47313723">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47313329" class="clicky" aria-hidden="true">parent</a> | <a href="#47315696" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Right but LLM companies are building frontier models with frontier talent while trying to sock up demand with a loss leader strategy, on top of an historic infrastructure build out.
<p>Being able to coat efficiently run frontier models is i think, not a high priced endeavor for an org (compared to an individual).</p>
<p>IMO the proposition is little fishy, but its not totally without merit and imo deserves investigation. If we are all worried about our jobs, even via building custom for sale software, there is likely something there that may obviate the need at least for end user applications. Again, im deeply skeptical, but it is interesting.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314384"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=overfeed" class="hnuser">overfeed</a> <a href="https://news.ycombinator.com/item?id=47314384">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47313723" class="clicky" aria-hidden="true">parent</a> | <a href="#47315696" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Being able to coat efficiently run frontier models is i think, not a high priced endeavor for an org
<p>Running proprietary model would make you subject to whatever ToS the LLM companies choose on a particular day, and what you can produce with them, which circles back to the raison d'etre for the GPL and GNU.</p>
<p>Until all software copyright is dead and buried, there is no need for copyleft to change tack. Otherwise there rising tide may rise high enough to drown GPL, but not proprietary software.</p>
<p>Open source is easier to counterfeit/license-launder/re-implement using LLMs because source code is much lower-hanging fruit, and is understood by more people than closed-source assembly.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315696"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=socalgal2" class="hnuser">socalgal2</a> <a href="https://news.ycombinator.com/item?id=47315696">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311929" class="clicky" aria-hidden="true">parent</a> | <a href="#47313045" class="clicky" aria-hidden="true">prev</a> | <a href="#47311816" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Maybe a good open source idea is to "seti at home" style crowd-source training, assuming that's possible.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311816"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=stebalien" class="hnuser">stebalien</a> <a href="https://news.ycombinator.com/item?id=47311816">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47311929" class="clicky" aria-hidden="true">prev</a> | <a href="#47311943" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Copyleft is a mirror of copyright, not a way to fight copyright. It grants rights to the consumer where copyright grants rights to the creator. Importantly, it gives the end-user the right to modify the software running on their devices.
<p>Unfortunately, there are cases where you simply can't just "re-implement" something. E.g., because doing so requires access to restricted tools, keys, or proprietary specifications.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311968"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ordu" class="hnuser">ordu</a> <a href="https://news.ycombinator.com/item?id=47311968">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311816" class="clicky" aria-hidden="true">parent</a> | <a href="#47311898" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">These are words of Stallman:
<p><em>"So, I looked for a way to stop that from happening. The method I came up with is called “copyleft.” It's called copyleft because it's sort of like taking copyright and flipping it over. [Laughter] Legally, copyleft works based on copyright. We use the existing copyright law, but we use it to achieve a very different goal."</em></p>
<p><a href="https://writings.hongminhee.org/2026/03/legal-vs-legitimate/" rel="nofollow">https://writings.hongminhee.org/2026/03/legal-vs-legitimate/</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312201"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dathinab" class="hnuser">dathinab</a> <a href="https://news.ycombinator.com/item?id=47312201">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311968" class="clicky" aria-hidden="true">parent</a> | <a href="#47312156" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; flipping it over.
<p>i.e. mirroring it</p>
<p>&gt; use it to achieve a very different goal."</p>
<p>"very different goal" isn't the same as "fundamentally destroying copyright"</p>
<p>the very different goal include to protect public code to stay public, be properly attributed, prevent companies from just "sizing" , motivate other to make their code public too etc.</p>
<p>and even if his goals where not like that, it wouldn't make a difference as this is what many people try to archive with using such licenses</p>
<p>this kind of AI usage is very much not in line with this goals,</p>
<p>and in general way cheaper to do software cloning isn't sufficient to fix many of the issues the FOSS movement tried to fix, especially not when looking at the current ecosystem most people are interacting with (i.e. Phones)</p>
<p>---</p>
<p>("sizing"): As in the typical MS embrace, extend and extinguish strategy of first embracing the code then giving it proprietary but available extensions/changes/bug fixes/security patches to then make them no longer available if you don't pay them/play by their rules.</p>
<p>---</p>
<p>Through in the end using AI as a "fancy complicated" photocopier for code is as much removing copyright as using a photocopier for code would. It doesn't matter if you use the photocopier blind folded and never looked at the thing you copied.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312156"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sarchertech" class="hnuser">sarchertech</a> <a href="https://news.ycombinator.com/item?id=47312156">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311968" class="clicky" aria-hidden="true">parent</a> | <a href="#47312201" class="clicky" aria-hidden="true">prev</a> | <a href="#47315475" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That’s not a rebuttal of the OP’s point. None of that says anything about fighting copyright. It literally says he flipped it which is wha the OP said when they said it’s a mirror.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315475"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sjunot" class="hnuser">sjunot</a> <a href="https://news.ycombinator.com/item?id=47315475">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311968" class="clicky" aria-hidden="true">parent</a> | <a href="#47312156" class="clicky" aria-hidden="true">prev</a> | <a href="#47311898" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; We use the existing copyright law, but we use it to achieve a very different goal.
<p>For the right goal, he should have called it "rightcopy".</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311898"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rileymat2" class="hnuser">rileymat2</a> <a href="https://news.ycombinator.com/item?id=47311898">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311816" class="clicky" aria-hidden="true">parent</a> | <a href="#47311968" class="clicky" aria-hidden="true">prev</a> | <a href="#47311943" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">&gt; It grants rights to the consumer where copyright grants rights to the creator.
<p>It also grants one major right/feature to the creator, the ability to spread their work while keeping it as open as they intend.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311943"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cubefox" class="hnuser">cubefox</a> <a href="https://news.ycombinator.com/item?id=47311943">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47311816" class="clicky" aria-hidden="true">prev</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's naive. Copyright doesn't just apply to software. There already have been countless lawsuits about copying music long before the term "open source" was invented. No, changing the lyrics a bit doesn't circumvent copyright. Nor does translating a Stephen King novel to German and switching the names of the places and characters.
<p>A court ordered the first Nosferatu movie to be destroyed because it had too many similarities to Dracula. Despite the fact that the movie makes rather large deviations from the original.</p>
<p>If Claude was indeed asked to reimplement the existing codebase, just in Rust and a bit optimized, that could well be a copyright violation. Just like rephrasing <em>A Song ot Ice and Fire</em> a bit, and switching to a different language, doesn't remove its copyright.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312338"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zozbot234" class="hnuser">zozbot234</a> <a href="https://news.ycombinator.com/item?id=47312338">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311943" class="clicky" aria-hidden="true">parent</a> | <a href="#47315547" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Claude was asked to implement a public API, not an entire codebase. The definition of a public API is largely functional; even in an unusually complex case like the Java standard facilities (which are unusually creative even in the structure and organization of the API itself) the reimplementation by Google was found to be fair use.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312746"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cubefox" class="hnuser">cubefox</a> <a href="https://news.ycombinator.com/item?id=47312746">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312338" class="clicky" aria-hidden="true">parent</a> | <a href="#47315547" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Claude was asked to implement a public API, not an entire codebase.
<p>Allegedly. There have been several people who doubted this story. So how to find out who is right? Well, just let Claude compare the sources. Coincidentally, Claude Opus 4.6 doesn't just score 75.6% on SWE-bench Verified but also 90.2% on BigLaw Bench.</p>
<p>It's like our copyright lawyer is conveniently also a developer. And possibly identical to the AI that carried out the rewrite/reimplemention in question in the first place.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315547"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Marsymars" class="hnuser">Marsymars</a> <a href="https://news.ycombinator.com/item?id=47315547">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311943" class="clicky" aria-hidden="true">parent</a> | <a href="#47312338" class="clicky" aria-hidden="true">prev</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Just like rephrasing A Song ot Ice and Fire a bit, and switching to a different language, doesn't remove its copyright.
<p>There is some precedent for this, e.g. <em>Alchemised</em> is a recent best seller that had just enough changed from its Harry Potter fan fiction source in order to avoid copyright infringement: <a href="https://en.wikipedia.org/wiki/Alchemised" rel="nofollow">https://en.wikipedia.org/wiki/Alchemised</a></p>
<p>(I avoided the term “remove copyright” here because the new work is still under copyright, just not Harry Potter - related copyright.)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315565"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cubefox" class="hnuser">cubefox</a> <a href="https://news.ycombinator.com/item?id=47315565">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315547" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's apparently a different story with different plot, so that's not comparable.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317059"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Marsymars" class="hnuser">Marsymars</a> <a href="https://news.ycombinator.com/item?id=47317059">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315565" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Plots are broadly not copyrightable, “different plot” is <em>less</em> important than “different characters”.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317917"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cubefox" class="hnuser">cubefox</a> <a href="https://news.ycombinator.com/item?id=47317917">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47317059" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm pretty sure the plot is copyrightable, otherwise you could just translate Harry Potter to a different language and change the names of the characters.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318916"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Marsymars" class="hnuser">Marsymars</a> <a href="https://news.ycombinator.com/item?id=47318916">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47317917" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well the general guideline is that copyright covers the *expression of an idea*, not the idea itself.
<p>Translations are pretty much the textbook example of a derivative work in copyright.</p>
<p>Your jurisdiction may vary, of course, but it's pretty well established in mine (Canada) that "plot" is an idea, and can't be copyrighted, only the expression of the idea (e.g. the written novel) falls under copyright.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319116"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cubefox" class="hnuser">cubefox</a> <a href="https://news.ycombinator.com/item?id=47319116">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47318916" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If I translate Harry Potter to another language and change all the names, the resulting book clearly expresses the same ideas as the original.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47327884"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Marsymars" class="hnuser">Marsymars</a> <a href="https://news.ycombinator.com/item?id=47327884">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47319116" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes, I agree.
<p>But "expresses the same idea" isn't the benchmark, "ideas expressed in the same way" is the benchmark.</p>
<p>A translated work <em>is</em> "ideas expressed in the same way", a translation doesn't change that.</p>
<p>See e.g. this question/top answer on stackexchange, it details pretty well how plot can't be copyrighted using Harry Potter as an example: <a href="https://writing.stackexchange.com/questions/3928/on-copyright-laws-and-plots" rel="nofollow">https://writing.stackexchange.com/questions/3928/on-copyrigh...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312111"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=johnofthesea" class="hnuser">johnofthesea</a> <a href="https://news.ycombinator.com/item?id=47312111">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47311943" class="clicky" aria-hidden="true">prev</a> | <a href="#47314218" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; AI is eroding copyright, so there may no longer be a need for the GPL. GNU should stop and rethink its stance, chuck away the GPL as the main tool to fight evil software corporations and embrace LLM as the main weapon.
<p>Is this LLM thing freely available or is it owned and controlled by these companies? Are we going to rent the tools to fight "evil software corporations"?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315962"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Aozora7" class="hnuser">Aozora7</a> <a href="https://news.ycombinator.com/item?id=47315962">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312111" class="clicky" aria-hidden="true">parent</a> | <a href="#47315698" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There already are LLMs with open weights that are better at code than state of the art closed source models from a year ago. For now, you most people may have to rent the hardware to run those models, since it's too expensive for most people to own something that can run inference on one trillion parameters, but I wouldn't consider LLMs to be controlled by "evil software corporations" at this point.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317741"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lkjdsklf" class="hnuser">lkjdsklf</a> <a href="https://news.ycombinator.com/item?id=47317741">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315962" class="clicky" aria-hidden="true">parent</a> | <a href="#47315698" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">&gt; There already are LLMs with open weights that are better at code than state of the art closed source models from a year ago.
<p>A year ago, the "state of the art" models were total turds. So this isn't exactly good news</p>
<p>Not to mention the performance of local LLMs makes them utterly unusable unless you have multiple tens of thousands to invest in hardware (and that was before the recent price spike). If you're using commodity hardware, they're just awful to use.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315698"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=josephg" class="hnuser">josephg</a> <a href="https://news.ycombinator.com/item?id=47315698">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312111" class="clicky" aria-hidden="true">parent</a> | <a href="#47315962" class="clicky" aria-hidden="true">prev</a> | <a href="#47312228" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Open models do exist. They’re nowhere near aa good as frontier models, but they’re getting better all the time.
<p>It’s probably only a matter of time before open models are as good as Claude code is today.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315969"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Aozora7" class="hnuser">Aozora7</a> <a href="https://news.ycombinator.com/item?id=47315969">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47315698" class="clicky" aria-hidden="true">parent</a> | <a href="#47312228" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">With the release of GLM-5, I would say that they are pretty much almost as good. Basically 90% as good as Opus 4.6 on most tasks for 20% of inference cost, and open weights.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312228"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cozzyd" class="hnuser">cozzyd</a> <a href="https://news.ycombinator.com/item?id=47312228">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312111" class="clicky" aria-hidden="true">parent</a> | <a href="#47315698" class="clicky" aria-hidden="true">prev</a> | <a href="#47314218" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">easy, we ask Claude to write an open-source freely-available version of Claude with equal or better capabilities.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319204"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vips7L" class="hnuser">vips7L</a> <a href="https://news.ycombinator.com/item?id=47319204">2 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312228" class="clicky" aria-hidden="true">parent</a> | <a href="#47314218" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Make no mistakes.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314218"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Peritract" class="hnuser">Peritract</a> <a href="https://news.ycombinator.com/item?id=47314218">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47312111" class="clicky" aria-hidden="true">prev</a> | <a href="#47312043" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; chuck away the GPL as the main tool to fight evil software corporations and embrace LLM as the main weapon.
<p>LLMs are one of the primary manifestations of 'evil software corporations' currently.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312043"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dathinab" class="hnuser">dathinab</a> <a href="https://news.ycombinator.com/item?id=47312043">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47314218" class="clicky" aria-hidden="true">prev</a> | <a href="#47311950" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; we'll see that it was an attempt to fight copyrights with copyrights
<p>it's not that simple</p>
<p>yes, GPLs origins have the idea of "everyone should be able to use"</p>
<p>but it also is about attribution the original author</p>
<p>and making sure people can't just de-facto "size public goods"</p>
<p>the kind of AI usage is removing attribution and is often sizing public goods in a way far worse then most companies which just ignored the license did</p>
<p>so today there is more need then ever in the last few decades for GPL like licenses</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312315"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amiga386" class="hnuser">amiga386</a> <a href="https://news.ycombinator.com/item?id=47312315">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312043" class="clicky" aria-hidden="true">parent</a> | <a href="#47311950" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You've said "size" twice in comments, did you mean "seize"?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311950"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=webstrand" class="hnuser">webstrand</a> <a href="https://news.ycombinator.com/item?id=47311950">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47312043" class="clicky" aria-hidden="true">prev</a> | <a href="#47317024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Its purpose "if you run the software you should be able to inspect and modify that software, and to share those modifications with your peers" not explicitly resist copyright. Yes copyright is bad in that it often prevents one from doing that, but it is not the purpose of the GPL to dismantle copyright.
<p>Reducing it to "well you can clone the proprietary software you're forced to use by LLM" is really missing the soul of the GPL.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312280"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pocksuppet" class="hnuser">pocksuppet</a> <a href="https://news.ycombinator.com/item?id=47312280">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47311950" class="clicky" aria-hidden="true">parent</a> | <a href="#47317024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If not for copyright, you could always do that and copyleft wouldn't be needed.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314526"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=webstrand" class="hnuser">webstrand</a> <a href="https://news.ycombinator.com/item?id=47314526">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312280" class="clicky" aria-hidden="true">parent</a> | <a href="#47317024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Just because something is copyleft doesn't mean the person who gave you the binary you're using has to supply you with the code the used to build it. That's what the GPL does.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47353414"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pocksuppet" class="hnuser">pocksuppet</a> <a href="https://news.ycombinator.com/item?id=47353414">9 hours ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47314526" class="clicky" aria-hidden="true">parent</a> | <a href="#47317024" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's... the very <em>definition</em> of copyleft. If it's not like the GPL, it's not copyleft.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317024"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=paxys" class="hnuser">paxys</a> <a href="https://news.ycombinator.com/item?id=47317024">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47311950" class="clicky" aria-hidden="true">prev</a> | <a href="#47312162" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Until there is a capable open source open weight AI that is easily hostable by an average person - no, we still have a long way to go. You aren't going to have software freedom when the tool that enables it is controlled by a handful of powerful tech companies.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312162"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thomastjeffery" class="hnuser">thomastjeffery</a> <a href="https://news.ycombinator.com/item?id=47312162">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47317024" class="clicky" aria-hidden="true">prev</a> | <a href="#47314914" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">While I personally agree with you, Richard Stallman (the creator of the GPL) does not. He has always advocated in favor of strong copyright protection, because the foundation of the GPL is the monopoly power granted by copyright. The problem that the GPL is intended to solve is <em>proprietary software</em>.
<p>Generative models (AI) are not really eroding copyright. They are calling its bluff. The very notion of intellectual property depends on a property line: some arbitrary boundary where the property begins and ends. Generative models blur that line, making it impractical to distinguish which property belongs to whom.</p>
<p>Ironically, these models are made by giant monopolistic corporations whose wealth is quite literally a market valuation (stock price) of their copyrights! If generative models ever become good enough to reimplement CUDA, what value will NVIDIA have left?</p>
<p>The reality is that generative models are nowhere near good enough to actually call the bluff. Copyright is still the winning hand, and that is likely to continue, particularly while IP holders are the primary authors of law.</p>
<p>---</p>
<p>This whole situation is missing the forest for the trees. Intellectual Property is <em>bullshit</em>. A system predicated on monopoly power can only result in consolidated wealth driving the consolidation of power; which is precisely what has happened. The words "starving artist" ring every bit as familiar today as any time in history. Copyright has utterly failed the very goals it was explicitly written with.</p>
<p>It isn't the GPL that needs changing. So long as a system of copyright rules the land, copyleft is the best way to participate. What we really need is a cohesive political movement against monopoly power; one that <em>isn't</em> conveniently ignorant of copyright as its most significant source.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314863"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pennomi" class="hnuser">pennomi</a> <a href="https://news.ycombinator.com/item?id=47314863">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">root</a> | <a href="#47312162" class="clicky" aria-hidden="true">parent</a> | <a href="#47314914" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Right, anything that can be copied instantly for free cannot be realistically owned.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314914"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mikkupikku" class="hnuser">mikkupikku</a> <a href="https://news.ycombinator.com/item?id=47314914">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47312162" class="clicky" aria-hidden="true">prev</a> | <a href="#47312303" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree with almost all of that, except the part about GNU changing their stance. I think GNU should stay true and consistent, if for no other reason than to not make many of their supporters who aren't on board with AI feel betrayed and have GNUs legacy soured. If the cause of LLMs conquering proprietary software needs an organization to champion it, let that be a new organization, not GNU.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312303"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=re-thc" class="hnuser">re-thc</a> <a href="https://news.ycombinator.com/item?id=47312303">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47314914" class="clicky" aria-hidden="true">prev</a> | <a href="#47313490" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; What AI are eroding is copyright.
<p>At the moment it's people that are eroding copyright. E.g. in this case someone did something.</p>
<p>"AI" didn't have a brain, woke up and suddenly decided to do it.</p>
<p>Realistically nothing to do with AI. Having a gun doesn't mean you randomly shoot.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313490"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=xantronix" class="hnuser">xantronix</a> <a href="https://news.ycombinator.com/item?id=47313490">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47312303" class="clicky" aria-hidden="true">prev</a> | <a href="#47314334" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">So not only are we moving goalposts here, but we've decided the GNU team should join the other team? I don't understand how GNU would see mass model LLM training as anything but the most flagrant violations of their ethos. LLM labs, in their view, would be among the most evil software corporations to have ever existed.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314334"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wolvesechoes" class="hnuser">wolvesechoes</a> <a href="https://news.ycombinator.com/item?id=47314334">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47313490" class="clicky" aria-hidden="true">prev</a> | <a href="#47316471" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; AI is eroding copyright
<p>Unless it is IP of the same big corpos that consumed all content available. Good luck with eroding them.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316471"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47316471">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">parent</a> | <a href="#47314334" class="clicky" aria-hidden="true">prev</a> | <a href="#47311673" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">This is naive. Advertisement and network effects win. Individuals cannot compete with corporations on equal ground here.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311673"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sharkjacobs" class="hnuser">sharkjacobs</a> <a href="https://news.ycombinator.com/item?id=47311673">3 days ago</a> | <a href="#47311665" class="clicky" aria-hidden="true">prev</a> | <a href="#47315788" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard's account is that he never looked at the existing source code directly. He fed only the API and the test suite to Claude and asked it to reimplement the library from scratch
<p>This feels sort of like saying "I just blindly threw paint at that canvas on the wall and it came out in the shape of Mickey Mouse, and so it can't be copyright infringement because it was created without the use of my knowledge of Micky Mouse"</p>
<p>Blanchard is, of course, familiar with the source code, he's been its maintainer for years. The premise is that he prompted Claude to reimplement it, without using his own knowledge of it to direct or steer.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311926"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dathinab" class="hnuser">dathinab</a> <a href="https://news.ycombinator.com/item?id=47311926">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47311933" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard is, of course, familiar with the source code, he's been its maintainer for years.
<p>I would argue it's irrelevant if they looked or didn't look at the code. As well as weather he was or wasn't familiar with it.</p>
<p>What matters is, that they feed to original code into a tool which they setup to make a copy of it. How that tool works doesn't really matter. Neither does it make a difference if you obfuscate that it's an copy.</p>
<p>If I blindfold myself when making copies of books with a book scanner + printer I'm still engaging in copyright infringement.</p>
<p>If AI is a tool, that should hold.</p>
<p>If it isn't "just" a tool, then it did engage in copyright infringement (as it created the new output side by side with the original) in the same way an employee might do so on command of their boss. Which still makes the boss/company liable for copyright infringement and in general just because you weren't the one who created an infringing product doesn't mean you aren't more or less as liable of distributing it, as if you had done so.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314259"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Legend2440" class="hnuser">Legend2440</a> <a href="https://news.ycombinator.com/item?id=47314259">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311926" class="clicky" aria-hidden="true">parent</a> | <a href="#47312063" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;that they feed to original code into a tool which they setup to make a copy of it
<p>Well, no. They fed the spec (test cases, etc) into a tool which made a new program matching the spec. This is not a copy of the original code.</p>
<p>But also this feels like arguing over the color of the iceberg while the titanic sinks. If you have a tool that can make code to spec, what is the value in source code anymore? Even if your app is closed-source, you can just tell claude to write new code that does the same thing.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315864"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vbarrielle" class="hnuser">vbarrielle</a> <a href="https://news.ycombinator.com/item?id=47315864">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47314259" class="clicky" aria-hidden="true">parent</a> | <a href="#47314897" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Everyone writes as if he just fed the spec and tests to Claude Code. Ignoring for now that the tests are under LGPL as well, the commit history shows that this has been done with two weeks of steering Claude Code towards the desired output. At every one of these interactions, the maintainer used his deep knowledge of the chardet codebase to steer Claude.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318560"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=derangedHorse" class="hnuser">derangedHorse</a> <a href="https://news.ycombinator.com/item?id=47318560">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47315864" class="clicky" aria-hidden="true">parent</a> | <a href="#47314897" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is this perspective implying that the maintainer might be legally culpable because he, the *human*, was <em>trained</em> on the codebase?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320735"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vbarrielle" class="hnuser">vbarrielle</a> <a href="https://news.ycombinator.com/item?id=47320735">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47318560" class="clicky" aria-hidden="true">parent</a> | <a href="#47314897" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well I'm implying that someone who's been reading a codebase for 10+ years is the worst person to claim an "independent reimplementation".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314897"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=timeinput" class="hnuser">timeinput</a> <a href="https://news.ycombinator.com/item?id=47314897">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47314259" class="clicky" aria-hidden="true">parent</a> | <a href="#47315864" class="clicky" aria-hidden="true">prev</a> | <a href="#47312063" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Blanchard fed the spec to the tool, and Anthropic fed the code to the tool, so Blanchard didn't do anything wrong, and Anthropic didn't do anything wrong. Nothing to see here.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315396"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=foresto" class="hnuser">foresto</a> <a href="https://news.ycombinator.com/item?id=47315396">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47314897" class="clicky" aria-hidden="true">parent</a> | <a href="#47312063" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard fed the spec to the tool,
<p>Yes...</p>
<p>&gt; and Anthropic fed the code to the tool,</p>
<p>Presumably, as part of the massive amount of open-source code that must have been fed in to train their model.</p>
<p>&gt; so Blanchard didn't do anything wrong, and Anthropic didn't do anything wrong. Nothing to see here.</p>
<p>This is meant as irony, right?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47328501"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=timeinput" class="hnuser">timeinput</a> <a href="https://news.ycombinator.com/item?id=47328501">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47315396" class="clicky" aria-hidden="true">parent</a> | <a href="#47312063" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes. Specifically: The use of words to express something different from and often opposite to their literal meaning, and not some knifey spoony confusion.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312063"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=spullara" class="hnuser">spullara</a> <a href="https://news.ycombinator.com/item?id=47312063">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311926" class="clicky" aria-hidden="true">parent</a> | <a href="#47314259" class="clicky" aria-hidden="true">prev</a> | <a href="#47312934" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">if the actual text of the code isn't the same or obviously derivative, copyright doesn't apply at all.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312217"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sigseg1v" class="hnuser">sigseg1v</a> <a href="https://news.ycombinator.com/item?id=47312217">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312063" class="clicky" aria-hidden="true">parent</a> | <a href="#47313553" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What does derivative mean here? Because IMO it means that the existing work was used as input. So if you used a LLM and it was trained on the existing work, that's a derivative work. If you rot13 encode something as input, so you can't personally read it, and then a device decides to rot13 on it again and output it, that's a derivative work.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312360"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=spullara" class="hnuser">spullara</a> <a href="https://news.ycombinator.com/item?id=47312360">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312217" class="clicky" aria-hidden="true">parent</a> | <a href="#47312337" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In order for it to be creatively derivative you would need to copy the structure, logic, organization, and sequence of operations not just reimplement the functionality. It is pretty clear in this case that wasn't done.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315552"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cubefox" class="hnuser">cubefox</a> <a href="https://news.ycombinator.com/item?id=47315552">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312360" class="clicky" aria-hidden="true">parent</a> | <a href="#47312337" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's not clear at all.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312337"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ghostpepper" class="hnuser">ghostpepper</a> <a href="https://news.ycombinator.com/item?id=47312337">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312217" class="clicky" aria-hidden="true">parent</a> | <a href="#47312360" class="clicky" aria-hidden="true">prev</a> | <a href="#47312281" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">As a cynical person I assume all the frontier LLMs were trained on datasets that include every open source project, but as a thought experiment, if an LLM was trained on a dataset that included every open source project _execept_ chardet, do you think said LLM would still be able to easily implement something very similar?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312534"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=spullara" class="hnuser">spullara</a> <a href="https://news.ycombinator.com/item?id=47312534">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312337" class="clicky" aria-hidden="true">parent</a> | <a href="#47312281" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There is no doubt in my mind that it could still do it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312281"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nicole_express" class="hnuser">nicole_express</a> <a href="https://news.ycombinator.com/item?id=47312281">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312217" class="clicky" aria-hidden="true">parent</a> | <a href="#47312337" class="clicky" aria-hidden="true">prev</a> | <a href="#47313048" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Of course, the problem with this interpretation is that all modern LLMs are derivatives from huge amounts of text under completely different licenses, including "All rights reserved", and therefore can not be used for any purpose.
<p>I'm not sure how you square the circle of "it's alright to use the LLM to write code, unless the code is a rewrite of an open source project to change its license".</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315275"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=JoshTriplett" class="hnuser">JoshTriplett</a> <a href="https://news.ycombinator.com/item?id=47315275">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312281" class="clicky" aria-hidden="true">parent</a> | <a href="#47313048" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Of course, the problem with this interpretation is that all modern LLMs are derivatives from huge amounts of text under completely different licenses, including "All rights reserved", and therefore can not be used for any purpose.
<p>&gt; I'm not sure how you square the circle of "it's alright to use the LLM to write code</p>
<p>You seem like you're on the cusp of stating the obvious correct conclusion: it isn't.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313048"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47313048">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312217" class="clicky" aria-hidden="true">parent</a> | <a href="#47312281" class="clicky" aria-hidden="true">prev</a> | <a href="#47312580" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">&gt; <em>Because IMO it means that the existing work was used as input</em>
<p>That's your opinion (since you said "IMO"), not the actual legal definition.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312580"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bmcahren" class="hnuser">bmcahren</a> <a href="https://news.ycombinator.com/item?id=47312580">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312217" class="clicky" aria-hidden="true">parent</a> | <a href="#47313048" class="clicky" aria-hidden="true">prev</a> | <a href="#47312301" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">LLMs do not encode nor encrypt their training data. The fact they can recite training data is a defect not a default. You can understand this more simply by calculating the model size as an inverse of a fantasy compression algorithm that is 50% better than SOTA. You'll find you'd still be missing 80-90% of the training data even if it were as much of a stochastic parrot as you may be implying. The outputs of AI are not derivative just because they saw training data including the original library.
<p>Then onto prompting: 'He fed only the API and (his) test suite to Claude'</p>
<p>This is Google v Oracle all over again - are APIs copyrightable?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315763"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=thunderfork" class="hnuser">thunderfork</a> <a href="https://news.ycombinator.com/item?id=47315763">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312580" class="clicky" aria-hidden="true">parent</a> | <a href="#47313080" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I find the "compression" argument not very strong, both because copyright still applies to (very) lossy codecs (e.g. your 16kbps Opus file of Thriller infringes, even if the original 192khz/32bit wav file was 12,000kbps), and because copyright still applies to transformed derivative works (a tiny midi file of Thriller might still be enough for the Jackson's label to get you)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313080"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47313080">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312580" class="clicky" aria-hidden="true">parent</a> | <a href="#47315763" class="clicky" aria-hidden="true">prev</a> | <a href="#47316138" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>This is Google v Oracle all over again - are APIs copyrightable?</em>
<p>Yes this is the best way to ask the question. If I take a public facing API and reimplement everything, whether it's by human or machine, it should be sufficient. After all, that's what Google did, and it's not like their engineers never read a single line of the Java source code. Even in "clean room" implementations, a human might still have remembered or recalled a previous implementation of some function they had encountered before.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316138"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=azakai" class="hnuser">azakai</a> <a href="https://news.ycombinator.com/item?id=47316138">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312580" class="clicky" aria-hidden="true">parent</a> | <a href="#47313080" class="clicky" aria-hidden="true">prev</a> | <a href="#47319013" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; LLMs do not encode nor encrypt their training data. The fact they can recite training data is a defect not a default.
<p>About this specific point, it is unclear how much of a defect memorization actually is - there are also reasons to see it as necessary for effective learning. This link explains it well:</p>
<p><a href="https://infinitefaculty.substack.com/p/memorization-vs-generalization-in" rel="nofollow">https://infinitefaculty.substack.com/p/memorization-vs-gener...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319013"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tw1984" class="hnuser">tw1984</a> <a href="https://news.ycombinator.com/item?id=47319013">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312580" class="clicky" aria-hidden="true">parent</a> | <a href="#47316138" class="clicky" aria-hidden="true">prev</a> | <a href="#47312301" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; This is Google v Oracle all over again - are APIs copyrightable?
<p>No, it is completely different.</p>
<p>Claude was trained on chardet, anything built by Claude would fail the clean-room reimplementation test.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319147"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LegionMammal978" class="hnuser">LegionMammal978</a> <a href="https://news.ycombinator.com/item?id=47319147">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47319013" class="clicky" aria-hidden="true">parent</a> | <a href="#47312301" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"The clean-room reimplementation test" isn't a legal standard, it's a particular strategy used by would-be defendants to clearly meet the standard of "is the new work free of copyrightable expression from the original work".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312301"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wizzwizz4" class="hnuser">wizzwizz4</a> <a href="https://news.ycombinator.com/item?id=47312301">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312217" class="clicky" aria-hidden="true">parent</a> | <a href="#47312580" class="clicky" aria-hidden="true">prev</a> | <a href="#47313553" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">See also: <a href="https://monolith.sourceforge.net/" rel="nofollow">https://monolith.sourceforge.net/</a>, which seeks to ask the question:
<p>&gt; But how far away from direct and explicit representations do we have to go before copyright no longer applies?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313553"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=yorwba" class="hnuser">yorwba</a> <a href="https://news.ycombinator.com/item?id=47313553">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312063" class="clicky" aria-hidden="true">parent</a> | <a href="#47312217" class="clicky" aria-hidden="true">prev</a> | <a href="#47313254" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Copyright protects even very abstract aspects of human creative expression, not just the specific form in which it is originally expressed. If you translate a book into another language, or turn it into a silent movie, none of the actual text may survive, but the story itself remains covered by the original copyright.
<p>So when you clone the behavior of a program like chardet without referencing the original source code except by executing it to make sure your clone produces exactly the same output, you may still be infringing its copyright if that output reflects creative choices made in the design of chardet that aren't fully determined by the functional purpose of the program.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313254"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NSUserDefaults" class="hnuser">NSUserDefaults</a> <a href="https://news.ycombinator.com/item?id=47313254">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312063" class="clicky" aria-hidden="true">parent</a> | <a href="#47313553" class="clicky" aria-hidden="true">prev</a> | <a href="#47312934" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If you pirate a movie and reencode it, does that apply as well? You can still watch the movie and it is “obviously” the same movie, even though the bytes are completely different. Here you can use the program and it is, to the user, also the same.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312934"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=margalabargala" class="hnuser">margalabargala</a> <a href="https://news.ycombinator.com/item?id=47312934">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311926" class="clicky" aria-hidden="true">parent</a> | <a href="#47312063" class="clicky" aria-hidden="true">prev</a> | <a href="#47311933" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; If it isn't "just" a tool, then it did engage in copyright infringement
<p>Copyright infringement is a thing humans do. It's not a human.</p>
<p>Just like how the photos taken by a monkey with a camera have no copyright. Human law binds humans.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313082"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=malicka" class="hnuser">malicka</a> <a href="https://news.ycombinator.com/item?id=47313082">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312934" class="clicky" aria-hidden="true">parent</a> | <a href="#47311933" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Correct. The human who shares the copy is the one who engages in copyright infringement.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313316"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=margalabargala" class="hnuser">margalabargala</a> <a href="https://news.ycombinator.com/item?id=47313316">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313082" class="clicky" aria-hidden="true">parent</a> | <a href="#47311933" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">So, let's say that rather than actually touching any copyrighted material, a human merely tells an AI about how to go onto the internet and find copyrighted material, download it, and ingest it for training. The AI, fully autonomously, does so, and after training itself on the material deletes it so no human ever downloads, consumes, or shares it.
<p>If we are saying AI is "more than a tool", which seems to be the case courts are leaning since they've ruled AI output without direct human involvement is not copyrightable[0], then the above seems like it would be entirely legal.</p>
<p>[0] <a href="https://www.copyright.gov/newsnet/2025/1060.html" rel="nofollow">https://www.copyright.gov/newsnet/2025/1060.html</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315898"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Ekaros" class="hnuser">Ekaros</a> <a href="https://news.ycombinator.com/item?id=47315898">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313316" class="clicky" aria-hidden="true">parent</a> | <a href="#47311933" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Someone would likely get prosecuted if they instructed AI agent to run say a pump and dump scheme...
<p>Even if the final output doesn't have copyright protection it might still be copyright violation. I think it could be reasonable to have work that itself violates copyright when distributed even if it does not have copy right itself.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311933"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=logicprog" class="hnuser">logicprog</a> <a href="https://news.ycombinator.com/item?id=47311933">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47311926" class="clicky" aria-hidden="true">prev</a> | <a href="#47312655" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I just don't see how it's relevant whether he did look or didn't. In my opinion, it's not just legally valid to make a re-implementation of something if you've seen the code as long as it doesn't copy expressive elements. I think it's also ethically fine as well to use source code as a reference for re-implementing something as long as it doesn't turn into an exact translation.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312127"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=atomicnumber3" class="hnuser">atomicnumber3</a> <a href="https://news.ycombinator.com/item?id=47312127">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311933" class="clicky" aria-hidden="true">parent</a> | <a href="#47312613" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's actually not legally fine, or at least it's extremely dangerous. Projects that re-implement APIs presented by extremely litigious companies specifically do not allow people who, for instance, have seen the proprietary source code to then work on the project.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312219"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jpc0" class="hnuser">jpc0</a> <a href="https://news.ycombinator.com/item?id=47312219">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312127" class="clicky" aria-hidden="true">parent</a> | <a href="#47313081" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't think fear or legal action makes it illegal.
<p>If I know it is legal to make a turn at a red light. And I know a court will uphold that I was in the right but a police officer will fine me regardless and I would need to go to actually pursue some legal remedy I'm unlikely to do it regardless of whether it is legal because it is expensive, if not in money but time.</p>
<p>In the case of copyright lawsuits they are notoriously expensive and long so even if a court would eventually deem it fine, why take the chance.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315460"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=atomicnumber3" class="hnuser">atomicnumber3</a> <a href="https://news.ycombinator.com/item?id=47315460">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312219" class="clicky" aria-hidden="true">parent</a> | <a href="#47313081" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's my point. It's dangerous and there are sharks in the water. That sounds like you're not going to have a good time if you do the described approach to someone who might assert you're infringing.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313081"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sunshowers" class="hnuser">sunshowers</a> <a href="https://news.ycombinator.com/item?id=47313081">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312127" class="clicky" aria-hidden="true">parent</a> | <a href="#47312219" class="clicky" aria-hidden="true">prev</a> | <a href="#47312613" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">My understanding is that that is a maximalist position for the avoidance of risk, and is sufficient but probably not necessary.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312613"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=simonw" class="hnuser">simonw</a> <a href="https://news.ycombinator.com/item?id=47312613">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311933" class="clicky" aria-hidden="true">parent</a> | <a href="#47312127" class="clicky" aria-hidden="true">prev</a> | <a href="#47312097" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Right. The alternative is that we reward Dan for his 14 years of volunteer maintenance of a project... by banning him from working on anything similar under a different license for the rest of his life.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312097"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sarchertech" class="hnuser">sarchertech</a> <a href="https://news.ycombinator.com/item?id=47312097">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311933" class="clicky" aria-hidden="true">parent</a> | <a href="#47312613" class="clicky" aria-hidden="true">prev</a> | <a href="#47312655" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Ignoring the legal or ethical concerns. Let’s say we live in a world where the cost of copying code is so close to zero that it’s indistinguishable from a world without copyright.
<p>Anything you put out can and will be used by whatever giant company wants to use it with no attribution whatsoever.</p>
<p>Doesn’t that massively reduce the incentive to release the source of anything ever?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313105"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47313105">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312097" class="clicky" aria-hidden="true">parent</a> | <a href="#47317597" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, because (most) people don't work on OSS for vanity, they do it to help other people, whether it's individuals or groups of individuals, ie corporations.
<p>It's the same question as, if an AI can generate "art", or photographers can capture a scene better than any (realistic) painter, then will people still create art? Obviously yes, and we see it of course after Stable Diffusion was released three years ago, people are still creating.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315903"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sarchertech" class="hnuser">sarchertech</a> <a href="https://news.ycombinator.com/item?id=47315903">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313105" class="clicky" aria-hidden="true">parent</a> | <a href="#47317597" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don’t know what a world without copyright does to corporate sponsored open source. It certainly reduces it because there are many corporate sponsored projects that monetize through dual licensing. My guess is in a world where you can’t even guarantee attribution, it’s much harder to convince your boss to let you open source a project in the first place.
<p>So ignoring people who are being paid by corporations directly to work on open source, in my experience the vast majority of contributors expect to be able to monetize their work eventually in a way that requires attribution. And out of the small number who don’t expect a monetary return of any kind, a still smaller number don’t expect recognition.</p>
<p>If this weren’t the case you’d see a much larger amount of anonymous contributions. There are people who anonymously donate to charity. The vast majority want some kind of recognition.</p>
<p>Obviously we still see art, if you greatly reduce the monetary benefit to producing art, you’ll see a lot less of it. This is especially true of non trivial open source software that unlike static artwork requires continual maintenance.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317597"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=joshjob42" class="hnuser">joshjob42</a> <a href="https://news.ycombinator.com/item?id=47317597">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312097" class="clicky" aria-hidden="true">parent</a> | <a href="#47313105" class="clicky" aria-hidden="true">prev</a> | <a href="#47312368" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If the cost to copying code based on specifications, tests, etc is so close to zero as to be functionally zero cost, then any user can simply turn their AI on any library for which there is documentation and any ability to generate tests, have it reverse engineer it, and release their reverse engineered copy on GitHub for others to use as they like.
<p>So I'm not sure it matters whether a giant company uses it because random users can get the same thing for ~ free anyway.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319122"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sarchertech" class="hnuser">sarchertech</a> <a href="https://news.ycombinator.com/item?id=47319122">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47317597" class="clicky" aria-hidden="true">parent</a> | <a href="#47312368" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can mostly stop that with enoiugh lawyers and requiring and agreement not to reverse engineer to access documentation or use the software.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312368"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=intrasight" class="hnuser">intrasight</a> <a href="https://news.ycombinator.com/item?id=47312368">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312097" class="clicky" aria-hidden="true">parent</a> | <a href="#47317597" class="clicky" aria-hidden="true">prev</a> | <a href="#47312258" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Most commercial software that I've used has the model of a legal moat around a pretty crappy database schema.
<p>The non IP protection has largely been in the effort involved in replicating an application's behavior and that effort is dropping precipitously.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315955"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sarchertech" class="hnuser">sarchertech</a> <a href="https://news.ycombinator.com/item?id=47315955">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312368" class="clicky" aria-hidden="true">parent</a> | <a href="#47312258" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You must not have used much commercial software outside of crappy business SaaS.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317028"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=intrasight" class="hnuser">intrasight</a> <a href="https://news.ycombinator.com/item?id=47317028">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47315955" class="clicky" aria-hidden="true">parent</a> | <a href="#47312258" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Truth</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312258"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pocksuppet" class="hnuser">pocksuppet</a> <a href="https://news.ycombinator.com/item?id=47312258">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312097" class="clicky" aria-hidden="true">parent</a> | <a href="#47312368" class="clicky" aria-hidden="true">prev</a> | <a href="#47312655" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yes, and it reduces the incentives to release binaries too. Such a world will be populated by almost entirely SaaS, which can still compete on freedom.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312655"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=axus" class="hnuser">axus</a> <a href="https://news.ycombinator.com/item?id=47312655">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47311933" class="clicky" aria-hidden="true">prev</a> | <a href="#47312048" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oracle had it's day in court with Google over the Java APIs. Reimplementing APIs can be done without copyright infringement, but Oracle must have tried to find real infringement during discovery.
<p>In this case, we could theoretically prove that the new chardet is a clean reimplementation. Blanchard can provide all of the prompts necessary to re-implement again, and for the cost of the tokens anyone can reproduce the results.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312048"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Aurornis" class="hnuser">Aurornis</a> <a href="https://news.ycombinator.com/item?id=47312048">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47312655" class="clicky" aria-hidden="true">prev</a> | <a href="#47312166" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Can anyone find the actual quote where Blanchard said this?
<p>My understanding was that his claim was that <em>Claude</em> was not looking at the existing source code while writing it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318519"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=duskdozer" class="hnuser">duskdozer</a> <a href="https://news.ycombinator.com/item?id=47318519">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312048" class="clicky" aria-hidden="true">parent</a> | <a href="#47312174" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That is what he claimed. However, his design document instructs the AI to download the codebase, references specific files in the codebase, and to create a rewrite of the same project by name. It seems very unlikely it didn't look at the code while working, even forgetting that it had already likely been trained on it.
<p>He would have had a better argument if he created a matching spec from scratch using randomized names.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312174"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pklausler" class="hnuser">pklausler</a> <a href="https://news.ycombinator.com/item?id=47312174">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312048" class="clicky" aria-hidden="true">parent</a> | <a href="#47318519" class="clicky" aria-hidden="true">prev</a> | <a href="#47312260" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Conveniently ignoring the likelihood that Claude had been trained on the freely accessible source code.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312260"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mrgoldenbrown" class="hnuser">mrgoldenbrown</a> <a href="https://news.ycombinator.com/item?id=47312260">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312048" class="clicky" aria-hidden="true">parent</a> | <a href="#47312174" class="clicky" aria-hidden="true">prev</a> | <a href="#47312166" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Does he have access to Claude's training data? How can he claim Claude wasn't trained on the original code?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312166"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=SpicyLemonZest" class="hnuser">SpicyLemonZest</a> <a href="https://news.ycombinator.com/item?id=47312166">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47312048" class="clicky" aria-hidden="true">prev</a> | <a href="#47315709" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Isn't this a red herring? An API definition is fair use under Google v. Oracle, but the test suite is definitely copyrightable code!</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315709"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47315709">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47312166" class="clicky" aria-hidden="true">prev</a> | <a href="#47312044" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;This feels sort of like saying "I just blindly threw paint at that canvas on the wall and it came out in the shape of Mickey Mouse, and so it can't be copyright infringement because it was created without the use of my knowledge of Micky Mouse"
<p>IANAL, but that analogy wouldn't work because Mickey Mouse is a trademark, so it doesn't matter how it is created.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312044"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=esafak" class="hnuser">esafak</a> <a href="https://news.ycombinator.com/item?id=47312044">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47315709" class="clicky" aria-hidden="true">prev</a> | <a href="#47311878" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If you only stick to the API and ignore the implementation, it is not Mickey Mouse any more but a rodent. If it was just a clone it wouldn't be 50x as fast. Nevertheless, APIs apparently can be copyrightable. I generally disagree with this; it's how PC compatibles took off, giving consumers better options.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312292"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amarant" class="hnuser">amarant</a> <a href="https://news.ycombinator.com/item?id=47312292">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312044" class="clicky" aria-hidden="true">parent</a> | <a href="#47311878" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Wait what, didn't oracle lose the case against Google? Have I been living in an alternate reality where API compatibility is fair use?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311878"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=re-thc" class="hnuser">re-thc</a> <a href="https://news.ycombinator.com/item?id=47311878">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47312044" class="clicky" aria-hidden="true">prev</a> | <a href="#47312616" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; This feels sort of like saying "I just blindly threw paint at that canvas on the wall and
<p>&gt; He fed only the API and the test suite to Claude and asked it</p>
<p>Difference being Claude looked; so not blind. The equivalent is more like I blindly took a photo of it and then used that to...</p>
<p>Technically did look.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312249"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amarant" class="hnuser">amarant</a> <a href="https://news.ycombinator.com/item?id=47312249">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47311878" class="clicky" aria-hidden="true">parent</a> | <a href="#47312616" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The article is poorly written. Blanchard was a chardet maintainer for years. Of course <em>he</em> had looked at it's code!
<p>What he claimed, and what was interesting, was that Claude <em>didn't</em> look at the code, only the API and the test suite. The new implementation is all Claude. And the implementation is different enough to be considered original, completely different structure, design, and hey, a 48x improvement in performance! It's just API-compatible with the original. Which as per the Google Vs oracle 2021 decision is to be considered fair use.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312343"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=re-thc" class="hnuser">re-thc</a> <a href="https://news.ycombinator.com/item?id=47312343">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312249" class="clicky" aria-hidden="true">parent</a> | <a href="#47312282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; What he claimed, and what was interesting, was that Claude didn't look at the code
<p>Who opened the PR? Who co-authored the commits? It's clearly on Github.</p>
<p>&gt; Blanchard was a chardet maintainer for years. Of course he had looked at its code!</p>
<p>So there you have it. If he looked, he co-authored then there's that.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313058"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kjksf" class="hnuser">kjksf</a> <a href="https://news.ycombinator.com/item?id=47313058">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312343" class="clicky" aria-hidden="true">parent</a> | <a href="#47312282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If I put my signature on Picasso painting, it doesn't make me co-author of said painting.
<p>Blanchard is very clear that he didn't write a single line of code. He isn't an author, he isn't a co-author.</p>
<p>Signing GitHub commit doesn't change that.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313098"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=re-thc" class="hnuser">re-thc</a> <a href="https://news.ycombinator.com/item?id=47313098">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313058" class="clicky" aria-hidden="true">parent</a> | <a href="#47312282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard is very clear that he didn't write a single line of code
<p>He used Claude to write it. Difference? The fact that I write on the notepad vs printed it out = I didn't do it?</p>
<p>&gt; Signing GitHub commit doesn't change that.</p>
<p>That's the equivalent of me saying I didn't kill anyone. The fingerprints on the knife doesn't change that.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313137"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47313137">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313098" class="clicky" aria-hidden="true">parent</a> | <a href="#47312282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'll take a commit authored by someone else and then git amend the author to myself, did I write that commit then? By your logic I did apparently.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320448"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=re-thc" class="hnuser">re-thc</a> <a href="https://news.ycombinator.com/item?id=47320448">2 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313137" class="clicky" aria-hidden="true">parent</a> | <a href="#47312282" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; I'll take a commit authored by someone else and then git amend the author to myself, did I write that commit then
<p>I did say co-author didn't I? Even if you added 0.000000001% to something you did so technically, yes.</p>
<p>&gt; By your logic I did apparently</p>
<p>If you take someone's email and forward it did you write that email? Instead of debating that imagine you took a trojan email and forwarded it to someone and they opened it - do you think you'd be held up in any way?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312282"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mrgoldenbrown" class="hnuser">mrgoldenbrown</a> <a href="https://news.ycombinator.com/item?id=47312282">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312249" class="clicky" aria-hidden="true">parent</a> | <a href="#47312343" class="clicky" aria-hidden="true">prev</a> | <a href="#47312616" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">did he claim that Claude wasn't trained on the original? Or just that he didn't personally provide Claude with a copy?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312857"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amarant" class="hnuser">amarant</a> <a href="https://news.ycombinator.com/item?id=47312857">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312282" class="clicky" aria-hidden="true">parent</a> | <a href="#47312616" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I recon the latter, how would he know what was in Claude's training data?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312616"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=babypuncher" class="hnuser">babypuncher</a> <a href="https://news.ycombinator.com/item?id=47312616">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">parent</a> | <a href="#47311878" class="clicky" aria-hidden="true">prev</a> | <a href="#47315788" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if we said that generative AI output is simply not copyrightable. Anything an AI spits out would automatically be public domain, except in cases where the output directly infringes the rights of an existing work.
<p>This would make it so relicensing with AI rewrites is essentially impossible unless your goal is to transition the work to be truly public domain.</p>
<p>I think this also helps somewhat with the ethical quandary of these models being trained on public data while contributing nothing of value back to the public, and disincentivize the production of slop for profit.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313084"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kjksf" class="hnuser">kjksf</a> <a href="https://news.ycombinator.com/item?id=47313084">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312616" class="clicky" aria-hidden="true">parent</a> | <a href="#47313136" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">We did in fact say so.
<p><a href="https://www.carltonfields.com/insights/publications/2025/no-copyright-protection-for-ai-assisted-creations-thaler-v-perlmutter" rel="nofollow">https://www.carltonfields.com/insights/publications/2025/no-...</a></p>
<p>&gt; No Copyright Protection for AI-Assisted Creations: Thaler v. Perlmutter</p>
<p>&gt; A recent key judicial development on this topic occurred when the U.S. Supreme Court declined to review the case of Thaler v. Perlmutter on March 2, 2026, effectively upholding lower court rulings that AI-generated works lacking human authorship are not eligible for copyright protection under U.S. law</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313612"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pseudalopex" class="hnuser">pseudalopex</a> <a href="https://news.ycombinator.com/item?id=47313612">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47313084" class="clicky" aria-hidden="true">parent</a> | <a href="#47313136" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; &gt; A recent key judicial development on this topic occurred when the U.S. Supreme Court declined to review the case of Thaler v. Perlmutter on March 2, 2026, effectively upholding lower court rulings that AI-generated works lacking human authorship are not eligible for copyright protection under U.S. law
<p>This was AI summary? Those words were not in the article.</p>
<p>The courts said Thaler could not have copyright because he refused to list himself as an author.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313136"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=idle_zealot" class="hnuser">idle_zealot</a> <a href="https://news.ycombinator.com/item?id=47313136">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">root</a> | <a href="#47312616" class="clicky" aria-hidden="true">parent</a> | <a href="#47313084" class="clicky" aria-hidden="true">prev</a> | <a href="#47315788" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; This would make it so relicensing with AI rewrites is essentially impossible unless your goal is to transition the work to be truly public domain.
<p>That's not true at all. Anyone could follow these steps:</p>
<p>1. Have the LLM rewrite GPL code.</p>
<p>2. Do <em>not</em> publish that public domain code. You have no obligation to.</p>
<p>3. Make a few tweaks to that code.</p>
<p>4. Publish a compiled binary/use your code to host a service under a proprietary license of your choice.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315788"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Gigachad" class="hnuser">Gigachad</a> <a href="https://news.ycombinator.com/item?id=47315788">3 days ago</a> | <a href="#47311673" class="clicky" aria-hidden="true">prev</a> | <a href="#47312617" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Someone should put this to the test. Take the recently leaked Minecraft source code and have Copilot build an exact replica in another programming language and then publish it as open source. See if Microsoft believes AI is copyright infringement or not.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315872"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=robmccoll" class="hnuser">robmccoll</a> <a href="https://news.ycombinator.com/item?id=47315872">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47316492" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">As described, this would not be the same thing. If the AI is looking at the source and effectively porting it, that is likely infringement. The idea instead should be "implement Minecraft from scratch" but with behavior, graphics, etc. identical. Note that you'll need to have an AI generate assets or something since you can't just reuse textures and models.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315894"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Gigachad" class="hnuser">Gigachad</a> <a href="https://news.ycombinator.com/item?id=47315894">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315872" class="clicky" aria-hidden="true">parent</a> | <a href="#47316081" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">AI models have already looked at the source of GPL software and contain it in their dataset. Adding the minecraft source to the mix wouldn't seem much different. Of course art assets and trade marks would have to be replaced. But an AI "clean room" implementation has yet to be legally tested.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316071"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47316071">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315894" class="clicky" aria-hidden="true">parent</a> | <a href="#47316047" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's why he is saying it's not equivalent. For it to be the same, the LLM would have to train on/transform Minecraft's source code into its weights, then you prompt the LLM to make a game using the specifications of Minecraft solely through prompts. Of course it's copyright infringement if you just give a tool Minecraft's source code and tell it to copy it, just like it would be copyright infringement if you used a copier to copy Minecraft's source code into a new document and say you recreated Minecraft.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316930"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alpaca128" class="hnuser">alpaca128</a> <a href="https://news.ycombinator.com/item?id=47316930">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316071" class="clicky" aria-hidden="true">parent</a> | <a href="#47316605" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if Copilot was already trained with Minecraft code in the dataset? Should be possible to test by telling the model to continue a snippet from the leaked code, the same way a news website proved their articles were used for training.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317397"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47317397">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316930" class="clicky" aria-hidden="true">parent</a> | <a href="#47316605" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I feel as though the fact that you are asking a valid question shows how transformative it is; clearly, while the LLM gets a general ability to code from its training corpus, the data gets so transformed that it's difficult to tell what exactly it was trained on except a large body of code.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318207"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Gigachad" class="hnuser">Gigachad</a> <a href="https://news.ycombinator.com/item?id=47318207">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47317397" class="clicky" aria-hidden="true">parent</a> | <a href="#47317473" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This would still be true of the case where you ask an LLM to rewrite a program while referencing the source. Unless someone was in the room watching or the logs are inspected, how would they know if the LLM was referencing the original source material, or just using general programing knowledge to build something similar.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317473"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=RhythmFox" class="hnuser">RhythmFox</a> <a href="https://news.ycombinator.com/item?id=47317473">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47317397" class="clicky" aria-hidden="true">parent</a> | <a href="#47318207" class="clicky" aria-hidden="true">prev</a> | <a href="#47316605" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Then the training itself is the legal question. This doesn't seem all that complicated to me.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316605"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=paxys" class="hnuser">paxys</a> <a href="https://news.ycombinator.com/item?id=47316605">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316071" class="clicky" aria-hidden="true">parent</a> | <a href="#47316930" class="clicky" aria-hidden="true">prev</a> | <a href="#47317467" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is there a legal distinction between training, post-training, fine tuning and filling up a context window?
<p>In all of these cases an AI model is taking a copyrighted source, reading it, jumbling the bytes and storing it in its memory as vectors.</p>
<p>Later a query reads these vectors and outputs them in a form which may or may not be similar to the original.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316726"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=SatvikBeri" class="hnuser">SatvikBeri</a> <a href="https://news.ycombinator.com/item?id=47316726">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316605" class="clicky" aria-hidden="true">parent</a> | <a href="#47318497" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Judges have previously ruled that training counts as sufficiently transformative to qualify for fair use: <a href="https://www.whitecase.com/insight-alert/two-california-district-judges-rule-using-books-train-ai-fair-use" rel="nofollow">https://www.whitecase.com/insight-alert/two-california-distr...</a>
<p>I don't know of any rulings on the context window, but it's certainly possible judges would rule that would not qualify as transformative.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318497"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=derangedHorse" class="hnuser">derangedHorse</a> <a href="https://news.ycombinator.com/item?id=47318497">2 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316605" class="clicky" aria-hidden="true">parent</a> | <a href="#47316726" class="clicky" aria-hidden="true">prev</a> | <a href="#47317467" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The context window is quite literally not a transformation of tokens or a "jumbling of bytes," it's the exact tokens themselves. The context actually needs to get passed in on every request but it's abstracted from most LLM users by the chat interface.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317467"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=phendrenad2" class="hnuser">phendrenad2</a> <a href="https://news.ycombinator.com/item?id=47317467">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316071" class="clicky" aria-hidden="true">parent</a> | <a href="#47316605" class="clicky" aria-hidden="true">prev</a> | <a href="#47316047" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's not equivalent, but it's close enough that you can't easily dismiss it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316047"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=reverius42" class="hnuser">reverius42</a> <a href="https://news.ycombinator.com/item?id=47316047">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315894" class="clicky" aria-hidden="true">parent</a> | <a href="#47316071" class="clicky" aria-hidden="true">prev</a> | <a href="#47326963" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">For copyright purposes I think there is an important legal distinction between training data (fed in once, ahead of time, and can in theory no longer be recovered as-is) and context window data (stored exactly for the duration of the model call).
<p>I'm not sure there should be, but I think there is.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326963"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sneak" class="hnuser">sneak</a> <a href="https://news.ycombinator.com/item?id=47326963">2 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315894" class="clicky" aria-hidden="true">parent</a> | <a href="#47316047" class="clicky" aria-hidden="true">prev</a> | <a href="#47316081" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You are confusing training data with context (prompts).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316081"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NiloCK" class="hnuser">NiloCK</a> <a href="https://news.ycombinator.com/item?id=47316081">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315872" class="clicky" aria-hidden="true">parent</a> | <a href="#47315894" class="clicky" aria-hidden="true">prev</a> | <a href="#47317914" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A room "as clean" as the one under dispute (chardet) is very easy to replicate.
<p>AI 1: - (reads the source), creates a spec + acceptance criteria</p>
<p>AI 2: - implements from spec</p>
<p>AI 1 is in the position of the maintainer who facilitated the license swap.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317914"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=yunnpp" class="hnuser">yunnpp</a> <a href="https://news.ycombinator.com/item?id=47317914">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315872" class="clicky" aria-hidden="true">parent</a> | <a href="#47316081" class="clicky" aria-hidden="true">prev</a> | <a href="#47317652" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Note that you'll need to have an AI generate assets or something since you can't just reuse textures and models.
<p>As far as I know, you can as long as you own a copy of the original. In other words, you can't redistribute the assets, but you can distribute the code that works with them. This is literally how every free/libre game remake works. The copyright of your new, from-scratch code, is in no way linked to that of the assets.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317652"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=smsm42" class="hnuser">smsm42</a> <a href="https://news.ycombinator.com/item?id=47317652">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315872" class="clicky" aria-hidden="true">parent</a> | <a href="#47317914" class="clicky" aria-hidden="true">prev</a> | <a href="#47316492" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"Behavior, graphics, etc." would likely constitute separate IP from the code. I am not sure there's a model that allows you to make AI reproduce Minecraft without telling it what "Minecraft" is - which would likely contaminate it with IP-protected information.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316492"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=u1hcw9nx" class="hnuser">u1hcw9nx</a> <a href="https://news.ycombinator.com/item?id=47316492">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47315872" class="clicky" aria-hidden="true">prev</a> | <a href="#47315837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00"><em>This</em> was not about legality.
<p>&gt; That question is this: does legal mean legitimate?</p>
<p>Just because something is legal does not mean it's moral thing to do.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316522"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=larodi" class="hnuser">larodi</a> <a href="https://news.ycombinator.com/item?id=47316522">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316492" class="clicky" aria-hidden="true">parent</a> | <a href="#47315837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c88">this question should've been posed earlier when first LLMs were training. many people chose to ignore the question, and now, several distillation epochs later, it is not a question that matters, as both yes/no are true, and not true.
<p>is it legitimate for millions of people to exploit, expound on knowledge that was perhaps, to begin with, not legitimate to use? well they did already, who's to judge the commons now?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316747"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mirashii" class="hnuser">mirashii</a> <a href="https://news.ycombinator.com/item?id=47316747">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316522" class="clicky" aria-hidden="true">parent</a> | <a href="#47315837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What a ridiculous take. Many people loudly raised the question and objected to the practice from the beginning, but a handful of companies ignored the objections and ran faster than the legal system. If they were in the wrong, legally or morally, they still deserve to face repercussions for it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317845"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=larodi" class="hnuser">larodi</a> <a href="https://news.ycombinator.com/item?id=47317845">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316747" class="clicky" aria-hidden="true">parent</a> | <a href="#47315837" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">it is a take, ridiculous or not. the fact you rage against it implies its not as improbable as you may want it to be. besides ridiculousness is a very subjective matter, right? many things are super ridiculous in 2026 from 2020s perspective, and this just piles on top.
<p>to me is superb ridiculous to shun the comment though. but we'll be having this split for a while, that for sure.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315837"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Aboutplants" class="hnuser">Aboutplants</a> <a href="https://news.ycombinator.com/item?id=47315837">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47316492" class="clicky" aria-hidden="true">prev</a> | <a href="#47316428" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I’ve often thought that the key to fighting this is through this exact method. Turn the tool against them</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316428"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47316428">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47315837" class="clicky" aria-hidden="true">prev</a> | <a href="#47315860" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">They might not care. Products win not by quality or features but by advertisement, hype and network effects.
<p>The original implementation would still have the upper hand here. OTOH if I as a nobody create something cool, there's nothing stopping a huge corporation from "reimplementing" (=stealing) it and and using their huge advertising budget to completely overshadow me.</p>
<p>And that's how they like it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316584"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Gigachad" class="hnuser">Gigachad</a> <a href="https://news.ycombinator.com/item?id=47316584">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316428" class="clicky" aria-hidden="true">parent</a> | <a href="#47315860" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Given how hard companies like Nintendo and Microsoft have been taking down leaks or fan creations, it seems they very much do care about keeping this stuff locked down.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315860"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=peacebeard" class="hnuser">peacebeard</a> <a href="https://news.ycombinator.com/item?id=47315860">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47316428" class="clicky" aria-hidden="true">prev</a> | <a href="#47317442" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The big question is: if copyrighted material was used in the training material, is the LLM's output copyright infringement when it resembles the training material? In your example, you are taking the copyrighted material and giving it to the LLM as input and instructing the LLM to process it. Regardless of where the legal cards fall, this is a much less ambiguous scenario.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317387"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47317387">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315860" class="clicky" aria-hidden="true">parent</a> | <a href="#47316359" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's a couple of different issues here that all get mangled together. If you're producing effectively the same expression that's infringement. You draw Captain America from memory, it's still Captain America, and therefore infringement. If you draw Captain Canada by tracing around Captain America that's also infringement but of a different type.
<p>When it comes to software, again it's the expression that matters -- literally the actual source code. Software that does the same thing but uses entirely different code to do it is not the same expression. Like with the tracing example above, if you read the original source code then it's harder to claim that it isn't the same expression. This is why clean room implementations are necessary.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320896"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alex1sa" class="hnuser">alex1sa</a> <a href="https://news.ycombinator.com/item?id=47320896">2 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47317387" class="clicky" aria-hidden="true">parent</a> | <a href="#47316359" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The "clean room" concept gets really blurry with LLMs in practice. I build a SaaS product that uses AI to process unstructured voice input and map it to structured form fields. During development, we looked at how other tools solve similar problems — not their source code, but their public behavior and APIs.
<pre><code>  Now imagine an LLM trained on every GitHub repo doing the same thing at scale. The model has "seen" the source, but the output is statistically generated, not
  copied. Is that a clean room? The model never "read" the code the way a human would, but it clearly learned patterns from it.
  I think the practical answer is that clean room as a legal concept was designed for a world where reimplementation was expensive and intentional. When an LLM
  can do it in minutes from a spec, we need a different framework entirely.</code></pre></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47325654"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47325654">2 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47320896" class="clicky" aria-hidden="true">parent</a> | <a href="#47316359" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Clean room is merely a defence in case you get sued by someone saying that you copied the work. It's not legally necessary.
<p>If the presumption is that LLM training, despite reading all the source code of everything everywhere, ultimately doesn't actually contain that source code (in a compressed form) then that is the significant bit.</p>
<p>If training is truly doing something transformative, maybe even a machine analogy to human learning, then anything produced directly by that LLM without another work in it's context is an entirely new work. That's all that is important.</p>
<p>&gt; I think the practical answer is that clean room as a legal concept was designed for a world where reimplementation was expensive and intentional.</p>
<p>Whether or not it's expensive or intentional is immaterial. It always was and it's still true now. All that matters is that the actual expression, the real source code, is not copied. Clean room is just one way to have evidence that you didn't copy.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316359"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=LPisGood" class="hnuser">LPisGood</a> <a href="https://news.ycombinator.com/item?id=47316359">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315860" class="clicky" aria-hidden="true">parent</a> | <a href="#47317387" class="clicky" aria-hidden="true">prev</a> | <a href="#47317442" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think Disney ran into this with people generating Marvel characters etc</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317193"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=shagie" class="hnuser">shagie</a> <a href="https://news.ycombinator.com/item?id=47317193">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316359" class="clicky" aria-hidden="true">parent</a> | <a href="#47317442" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Fictional characters can have their own copyright.
<p><a href="https://www.nolo.com/legal-encyclopedia/protecting-fictional-characters-under-copyright-law.html" rel="nofollow">https://www.nolo.com/legal-encyclopedia/protecting-fictional...</a></p>
<p><a href="https://en.wikipedia.org/wiki/Copyright_protection_for_fictional_characters" rel="nofollow">https://en.wikipedia.org/wiki/Copyright_protection_for_ficti...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317442"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=GuB-42" class="hnuser">GuB-42</a> <a href="https://news.ycombinator.com/item?id=47317442">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47315860" class="clicky" aria-hidden="true">prev</a> | <a href="#47315853" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think it will become interesting when AI will be able to decompile binaries.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317493"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gowld" class="hnuser">gowld</a> <a href="https://news.ycombinator.com/item?id=47317493">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47317442" class="clicky" aria-hidden="true">parent</a> | <a href="#47315853" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Decompiling binaries is easy when they are C# or Java, even before AI. C# is a Microsoft language, and C# games have thriving mod communities with deep hooks into the core game, and detailed documentation reverse-engineered from the binary.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315853"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amelius" class="hnuser">amelius</a> <a href="https://news.ycombinator.com/item?id=47315853">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47317442" class="clicky" aria-hidden="true">prev</a> | <a href="#47316997" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You will probably run into design patents.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316195"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=VorpalWay" class="hnuser">VorpalWay</a> <a href="https://news.ycombinator.com/item?id=47316195">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47315853" class="clicky" aria-hidden="true">parent</a> | <a href="#47316997" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Software patents is not a thing in EU.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316652"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throw-qqqqq" class="hnuser">throw-qqqqq</a> <a href="https://news.ycombinator.com/item?id=47316652">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316195" class="clicky" aria-hidden="true">parent</a> | <a href="#47316808" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Very much is. "Software programs, as such" are exempt in the EPC article 52. However if the software program interacts with the world - if it has a "further technical effect" - it is patentable.
<p><a href="https://en.wikipedia.org/wiki/Software_patents_under_the_European_Patent_Convention#Patentability_under_European_Patent_Office_case_law" rel="nofollow">https://en.wikipedia.org/wiki/Software_patents_under_the_Eur...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316808"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amelius" class="hnuser">amelius</a> <a href="https://news.ycombinator.com/item?id=47316808">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316195" class="clicky" aria-hidden="true">parent</a> | <a href="#47316652" class="clicky" aria-hidden="true">prev</a> | <a href="#47316396" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I said design patents:
<p><a href="https://en.wikipedia.org/wiki/Design_patent" rel="nofollow">https://en.wikipedia.org/wiki/Design_patent</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316396"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=IshKebab" class="hnuser">IshKebab</a> <a href="https://news.ycombinator.com/item?id=47316396">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">root</a> | <a href="#47316195" class="clicky" aria-hidden="true">parent</a> | <a href="#47316808" class="clicky" aria-hidden="true">prev</a> | <a href="#47316997" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">They absolutely are. That's a myth.
<p>But also software patents and design patents are totally different things.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316997"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=fruitworks" class="hnuser">fruitworks</a> <a href="https://news.ycombinator.com/item?id=47316997">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">parent</a> | <a href="#47315853" class="clicky" aria-hidden="true">prev</a> | <a href="#47312617" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">this is the question of the hour. Imagine using this LLM proxy to license-strip major parts of leaked Windows source code to produce code for WINE.
<p>On top of all of this, there are the attempts at binary decompilation using LLMs and other new tools that have been discussed on this site recently.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312617"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kelseyfrog" class="hnuser">kelseyfrog</a> <a href="https://news.ycombinator.com/item?id=47312617">3 days ago</a> | <a href="#47315788" class="clicky" aria-hidden="true">prev</a> | <a href="#47315401" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In the corporate world, we've started using reimplementation as a way to access tooling that security won't authorize.
<p>Sec has a deny by default policy. Eng has a use-more-AI policy. Any code written in-house is accepted by default. You can see where this is going.</p>
<p>We've been using AI to reimplement tooling that security won't approve. The incentives conspired in the worst outcome, yet here we are. If you want a different outcome, you need to create different incentives.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316008"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kemitchell" class="hnuser">kemitchell</a> <a href="https://news.ycombinator.com/item?id=47316008">3 days ago</a> | <a href="#47312617" class="clicky" aria-hidden="true">parent</a> | <a href="#47315401" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not Invented Here's long, slow mutagenic march toward full antibiotic resistance continues apace.
<p>There is a fundamental corpo-cognitive dissonance, to boot. If "AI" is cheap enough and good enough to implement security-relevant software from `git init` repeatedly, why isn't it also cheap enough and good enough to assess and approve the security of third-party software at pace with internal adoption? Is there some basis to believe LLMs' leverage on production differs from its leverage on analysis of existing code?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315401"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=munk-a" class="hnuser">munk-a</a> <a href="https://news.ycombinator.com/item?id=47315401">3 days ago</a> | <a href="#47312617" class="clicky" aria-hidden="true">prev</a> | <a href="#47312824" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think the missing thing here is that the license violation already happened. Most of the big models trained on data in a manner that violated terms of service. We'll need a court case but I think it's extremely reasonable to consider any model trained on GPL code to be infected with open licensing requirements.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315588"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47315588">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">parent</a> | <a href="#47315555" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You might wish that were true, but there are very strong arguments it's not. Training on copyleft licensed code is not a license violation. Any more than a person reading it is. In copyright terms, it's such an extreme transformative use that copyright no longer applies. It's fair use.
<p>But agreed that we're waiting for a court case to confirm that. Although really, the main questions for any court cases are not going to be around the principle of fair use itself or whether training is transformative enough (it obviously is), but rather on the specifics:</p>
<p>1) Was any copyrighted material <em>acquired</em> legally (not applicable here), and</p>
<p>2) Is the LLM always providing a unique expression (e.g. not regurgitating books or libraries verbatim)</p>
<p>And in this particular case, they confirmed that the new implementation is 98.7% unique.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318224"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pessimizer" class="hnuser">pessimizer</a> <a href="https://news.ycombinator.com/item?id=47318224">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315588" class="clicky" aria-hidden="true">parent</a> | <a href="#47317133" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Training on copyleft licensed code is not a license violation. Any more than a person reading it is. In copyright terms, it's such an extreme transformative use that copyright no longer applies. It's fair use.
<p>This is just an assertion that you're making. There's no argument here. I'm aware that this is also an assertion that some judges have made.</p>
<p>My claim is that LLMs are not human, therefore when you apply words like "training" to them, you're only doing it metaphorically. It's no more "training" than copying code to a different hard drive is training that hard drive. And it's no more "transformative" than rar'ing or zipping the code, then unzipping it. I can't sell my jpgs of pngs I downloaded from Getty.</p>
<p>I have no idea how LLMs can be considered transformative work that immunizes me from owing the least bit of respect to the source material, but if I sample 2-6 second snatches from 10 different songs, put them through over 9000 filters and blend them into a new work, I owe money to everyone involved. I might even owe money to the people who wrote the filters, depending on the licensing.</p>
<p>&gt; 98.7% unique.</p>
<p>This doesn't mean anything. This is a meaningless arrangement of words. The way we figure out things are piracy is through provenance, not bizarre ad hoc measurements. If I read a book in Spanish and rewrite it in English, it doesn't suddenly become mine even though it's <em>96.6492387% unique.</em> Not even if I drop a few chapters, add in a couple of my own, and change the ending.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326641"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47326641">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47318224" class="clicky" aria-hidden="true">parent</a> | <a href="#47317133" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>This is just an assertion that you're making. There's no argument here.</em>
<p>...OK? Was somebody asking me for an "argument"? I'm just stating how things are currently understood.</p>
<p>&gt; <em>And it's no more "transformative" than rar'ing or zipping the code, then unzipping it.</em></p>
<p>That's obviously false, so I'm not sure what to tell you.</p>
<p>&gt; <em>but if I sample 2-6 second snatches from 10 different songs, put them through over 9000 filters and blend them into a new work, I owe money to everyone involved</em></p>
<p>You don't, actually, if they're no longer recognizable -- which they wouldn't be after "9000 filters". I don't know where you got that idea that you'd still owe money. And I've certainly never heard of an audio filter license that was contingent on commerical distribution.</p>
<p>&gt; <em>This doesn't mean anything. This is a meaningless arrangement of words.</em></p>
<p>Statistics are meaningful. Obviously you need to look at the actual identical lines. But if they're a bunch of trivial things like initializing variables with obvious names, then they don't count for much. And if you're adhering to the same API, you would expect to have some small percentage of lines happen to match. So the fact that this is &lt;2%, as opposed to 40%, is <em>hugely</em> significant as a first step of analysis.</p>
<p>I suggest you might find conversations here on HN more productive if you soften your tone a bit. Saying things like "this is just an assertion that you're making" or "this is a meaningless arrangement of words" is not generally going to make people want to respond to you.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317133"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jazzyjackson" class="hnuser">jazzyjackson</a> <a href="https://news.ycombinator.com/item?id=47317133">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315588" class="clicky" aria-hidden="true">parent</a> | <a href="#47318224" class="clicky" aria-hidden="true">prev</a> | <a href="#47315960" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Transformative is not the only component of determining fair use, there’s also the economic displacement aspect. If you’re doing a book report and include portions of the original (or provide an interface for viewing portions à la Google Books) you aren’t a threat to the original authors ability to make a living.
<p>If you’ve used copyrighted books and turned them into a free write-a-book machine, you are suddenly using the authors own works against them, in a way that a judge might rule is not very fair.</p>
<p>“ Effect of the use upon the potential market for or value of the copyrighted work: Here, courts review whether, and to what extent, the unlicensed use harms the existing or future market for the copyright owner’s original work. In assessing this factor, courts consider whether the use is hurting the current market for the original work (for example, by displacing sales of the original) and/or whether the use could cause substantial harm if it were to become widespread.”</p>
<p><a href="https://www.copyright.gov/fair-use/" rel="nofollow">https://www.copyright.gov/fair-use/</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317302"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47317302">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47317133" class="clicky" aria-hidden="true">parent</a> | <a href="#47315960" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sure. But it seems very difficult to argue that LLM's are harming that ability to make a living in a <em>direct</em> way.
<p>This is for the same reason that search results or search snippets aren't deemed to harm creators according to copyright. Yes there might be some percentage lost of sales. And truly, people may be buying less JavaScript tutorial books now that LLM's can teach you JavaScript or write it for you. But the relation is so <em>indirect</em>, there's very little chance a court would accept the argument.</p>
<p>Because what the LLM is doing is reading <em>tons</em> of JavaScript and JavaScript tutorials and resources online, and producing its own <em>transformed</em> JavaScript. And the effect of any <em>single</em> JavaScript tutorial book in its training set is so marginal to the final result, there's no direct effect.</p>
<p>And the reason this makes sense is that it's no different from a teacher reading 20 books on JavaScript and then writing their own that turns out to be a best-seller. Yes, it takes away from the previous best-sellers. But that's fine, because they're not copying any of the previous works directly. They're transforming the facts they learned into a new synthesis.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315960"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gspr" class="hnuser">gspr</a> <a href="https://news.ycombinator.com/item?id=47315960">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315588" class="clicky" aria-hidden="true">parent</a> | <a href="#47317133" class="clicky" aria-hidden="true">prev</a> | <a href="#47316409" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Training on copyleft licensed code is not a license violation. Any more than a person reading it is.
<p>Some might hold that we've granted persons certain exemptions, on account of them being persons. We do not have to grant machines the same.</p>
<p>&gt; In copyright terms, it's such an extreme transformative use that copyright no longer applies.</p>
<p>Has the model really performed an extreme transformation if it is able to produce the training data near-verbatim? Sure, it can <em>also</em> produce extremely transformed versions, but is that really relevant if it holds within it enough information for a (near-)verbatim reproduction?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316538"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47316538">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315960" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;Has the model really performed an extreme transformation if it is able to produce the training data near-verbatim? Sure, it can also produce extremely transformed versions, but is that really relevant if it holds within it enough information for a (near-)verbatim reproduction?
<p>I feel as though, from an information-theoretic standpoint, it can't be possible that an LLM (which is almost certainly &lt;1 TB big) can contain any substantial verbatim portion of its training corpus, which includes audio, images, and videos.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319497"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gspr" class="hnuser">gspr</a> <a href="https://news.ycombinator.com/item?id=47319497">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316538" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; I feel as though, from an information-theoretic standpoint, it can't be possible that an LLM (which is almost certainly &lt;1 TB big) can contain any substantial verbatim portion of its training corpus, which includes audio, images, and videos.
<p>It doesn't need to for my argument to make sense. It's a problem if it reproduces a single copyrighted work (near)-verbatim. Which we have plenty of examples of.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320899"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47320899">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47319497" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Do we? Even when people attempt to jail break most models with 1000s of prompts they are only able to get a paragraph or two of well known copyrighted works and some blocks of paraphrased text, and that's with giving it a substantially leading question.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321675"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gspr" class="hnuser">gspr</a> <a href="https://news.ycombinator.com/item?id=47321675">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47320899" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It surely doesn't matter how leading or contorted the prompt has to be if it shows that the model is encoding the copyrighted work verbatimly or nearly so.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47325221"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47325221">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47321675" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It definitely does, which is why I put substantial amount of verbatim material. If someone can recite the first paragraph of Harry Potter and the sorcerers stone from memory, it surely doesn't mean they have memorized the entire book.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47334926"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gspr" class="hnuser">gspr</a> <a href="https://news.ycombinator.com/item?id=47334926">1 day ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47325221" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Of course not. But if the passage they can recite is long enough that it is copyrightable, then surely distributing a thing that (contortedly or not) can do said recitation is a form of redistribution of the work itself?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47341310"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="360" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47341310">1 day ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47334926" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No. It is against their TOS to attempt to jailbreak their models. While I don't agree that the models can recite longer periods of verbatim copyrighted material, even if it could, the person who is at fault is the person subverting the system, not the creator of the system. If I steal a library book and make copies of it to distribute illegally, it wouldn't make sense to hold the library at fault for infringing on the book publisher's copyright.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47347699"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="400" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=gspr" class="hnuser">gspr</a> <a href="https://news.ycombinator.com/item?id=47347699">18 hours ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47341310" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This is an interesting take that I hadn't considered. Your analogy with a library break-in is good. I'll need to digest this. Thanks.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316427"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316427">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315960" class="clicky" aria-hidden="true">parent</a> | <a href="#47316538" class="clicky" aria-hidden="true">prev</a> | <a href="#47332434" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>We do not have to grant machines the same.</em>
<p>No we don't <em>have</em> to, but so far we do, because that's the most legally consistent. If you want to change that, you're going to need to pass new laws that may wind up radically redefining intellectual property.</p>
<p>&gt; <em>Has the model really performed an extreme transformation if it is able to produce the training data near-verbatim?</em></p>
<p>Of course it has, if the <em>transformation</em> is extreme, as it appears to be here. If I memorize the lyrics to a bunch of love songs, and then write my own love song where every line is new, nobody's going to successfully sue me just because I can sing a bunch of other songs from memory.</p>
<p>Also, it's not even remotely clear that the LLM <em>can</em> produce the training data near-verbatim. Generally it <em>can't</em>, unless it's something that it's been trained on with high levels of repetition.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316762"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=munk-a" class="hnuser">munk-a</a> <a href="https://news.ycombinator.com/item?id=47316762">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316427" class="clicky" aria-hidden="true">parent</a> | <a href="#47332434" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I want to briefly pick at this:
<p>&gt; you're going to need to pass new laws that may wind up radically redefining intellectual property</p>
<p>You're correct that this is one route to resolving the situation, but I think it's reasonable to lean more strongly into the original intent of intellectual property laws to defend creative works as a manner to sustain yourself that would draw a pretty clear distinction between human creativity and reuse and LLMs.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316947"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316947">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316762" class="clicky" aria-hidden="true">parent</a> | <a href="#47332434" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>into the original intent of intellectual property laws to defend creative works as a manner to sustain yourself</em>
<p>But you're missing the other half of copyright law, which is the original intent to promote the public good.</p>
<p>That's why fair use exists, for the public good. And that's why the main legal argument behind LLM training is fair use -- that the resulting product doesn't compete directly with the originals, and is in the public good.</p>
<p>In other words, if you write an autobiography, you're not losing significant sales because people are asking an LLM about your life.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47332434"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Paradigma11" class="hnuser">Paradigma11</a> <a href="https://news.ycombinator.com/item?id=47332434">1 day ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315960" class="clicky" aria-hidden="true">parent</a> | <a href="#47316427" class="clicky" aria-hidden="true">prev</a> | <a href="#47316409" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"Has the model really performed an extreme transformation if it is able to produce the training data near-verbatim?...."
<p>So do 10 000 chimpanzees on typewriters.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316409"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=madeofpalk" class="hnuser">madeofpalk</a> <a href="https://news.ycombinator.com/item?id=47316409">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315588" class="clicky" aria-hidden="true">parent</a> | <a href="#47315960" class="clicky" aria-hidden="true">prev</a> | <a href="#47316142" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A human reading a unit of work is not a “copy”. I’m pretty sure our legal systems agree that thought or sight is not copying something.
<p>Training an LLM inherently requires making a copy of the work. Even the initial act of loading it from the internet and copying it into memory to then train the LLM is a copy that can be governed by its license and copyright law</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316535"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=cortesoft" class="hnuser">cortesoft</a> <a href="https://news.ycombinator.com/item?id=47316535">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316409" class="clicky" aria-hidden="true">parent</a> | <a href="#47316500" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think you are confusing two different meanings of the word ‘copy’. The fact that a computer loads it into memory does not make it automatically a ‘copy’ in the copyright sense.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317768"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=madeofpalk" class="hnuser">madeofpalk</a> <a href="https://news.ycombinator.com/item?id=47317768">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316535" class="clicky" aria-hidden="true">parent</a> | <a href="#47318127" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It absolutely does! In law and the courts
<p>&gt; The court held that making RAM copies as an essential step in utilizing software was permissible under §117 of the Copyright Act even if they are used for a purpose that the copyright holder did not intend.</p>
<p><a href="https://en.wikipedia.org/wiki/Vault_Corp._v._Quaid_Software_Ltd" rel="nofollow">https://en.wikipedia.org/wiki/Vault_Corp._v._Quaid_Software_...</a>.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318127"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kg" class="hnuser">kg</a> <a href="https://news.ycombinator.com/item?id=47318127">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316535" class="clicky" aria-hidden="true">parent</a> | <a href="#47317768" class="clicky" aria-hidden="true">prev</a> | <a href="#47316500" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; The fact that a computer loads it into memory does not make it automatically a ‘copy’ in the copyright sense.
<p>IIRC this exact argument was made in the Blizzard vs bnetd case, wasn't it? Though I can't find confirmation on whether that argument was rejected or not...</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316500"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316500">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316409" class="clicky" aria-hidden="true">parent</a> | <a href="#47316535" class="clicky" aria-hidden="true">prev</a> | <a href="#47318812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>Training an LLM inherently requires making a copy of the work.</em>
<p>But that's not relevant here. Because the copyleft license does not prohibit that (and it's not even clear that <em>any</em> license <em>can</em> prohibit it, as courts may confirm it's fair use, as most people are currently assuming). That's why I noted under (1) that it's not applicable here.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316695"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=munk-a" class="hnuser">munk-a</a> <a href="https://news.ycombinator.com/item?id=47316695">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316500" class="clicky" aria-hidden="true">parent</a> | <a href="#47318812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's absolutely prohibited to copy and redistribute for commercial purposes materials that you're unlicensed to do so with. This isn't an issue when it comes to the copy-left scenario (though it may potentially enforce transitive licensing requirements on the copier that LLM runners don't want to follow) but it is a huge issue that has come up with LLM training.
<p>LLM training involves ingesting works (in a potentially transformative process) and partially reproduce them - that's a generally restricted action when it comes to licensing.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316890"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316890">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316695" class="clicky" aria-hidden="true">parent</a> | <a href="#47318812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>It's absolutely prohibited to copy and redistribute for commercial purposes materials that you're unlicensed to do so with.</em>
<p>Sure, but that's not what LLM's generally do, and it's certainly not what they're intended to do.</p>
<p>The LLM companies, and many other people, argue that training falls under <em>fair use</em>. One element of fair use is whether the purpose/character is sufficiently <em>transformative</em>, and transforming texts into weights without even a remote 1-1 correspondence is the transformation.</p>
<p>And this is why LLM companies ensure that partial reproduction <em>doesn't</em> happen during LLM usage, using a kind of copyrighted-text filter as a last check in case anything would unintentionally get through. (And it doesn't even tend to occur in the first place, except when the LLM is trained on a bunch of copies of the same text.)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316948"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=munk-a" class="hnuser">munk-a</a> <a href="https://news.ycombinator.com/item?id=47316948">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316890" class="clicky" aria-hidden="true">parent</a> | <a href="#47318812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yea, at the end of the day a big part of this question comes down to whether that copying is fair use and that is an open question with the transformative nature being the primary point in favor of the LLM. But it is copying from some works to another - if it doesn't have some fair use exception it is absolutely violating the licensing of most of the training data. It's a bit different from previous settled case law because it's copying so little from so many billions of different things. I think blocking reproduction is wise by LLM companies for PR purposes but it doesn't guarantee that training is a license exempted activity.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320165"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=strogonoff" class="hnuser">strogonoff</a> <a href="https://news.ycombinator.com/item?id=47320165">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316948" class="clicky" aria-hidden="true">parent</a> | <a href="#47316966" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Would it be fair to say that if you steal from enough people then it becomes OK? I can’t see it—especially considering this is IP law, expected to grant people confidence in their authorship rights and thus encourage innovation and creativity.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320421"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="320" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=duskdozer" class="hnuser">duskdozer</a> <a href="https://news.ycombinator.com/item?id=47320421">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47320165" class="clicky" aria-hidden="true">parent</a> | <a href="#47316966" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">it's "if you steal fast enough and ubiquitously enough, then you win" where the goal is you've so entrenched your position that by the time a lawsuit rolls around, there isn't any real remedy. ideally, there would have been a day 1 lawsuit and injunction.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316966"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316966">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316948" class="clicky" aria-hidden="true">parent</a> | <a href="#47320165" class="clicky" aria-hidden="true">prev</a> | <a href="#47318812" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yup. Of course it's copying. But all expectations are that courts will rule that fair use allows such copying, because of the nature of the transformation.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318812"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=joquarky" class="hnuser">joquarky</a> <a href="https://news.ycombinator.com/item?id=47318812">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316409" class="clicky" aria-hidden="true">parent</a> | <a href="#47316500" class="clicky" aria-hidden="true">prev</a> | <a href="#47316142" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">We've drifted a bit off the road from "To promote the progress of science and useful arts"</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316142"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Copyrightest" class="hnuser">Copyrightest</a> <a href="https://news.ycombinator.com/item?id=47316142">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315588" class="clicky" aria-hidden="true">parent</a> | <a href="#47316409" class="clicky" aria-hidden="true">prev</a> | <a href="#47315555" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The big difference between people reading code and LLMs reading code is that people have legal liability and LLMs do not. You can't sue an LLM for copyright infringement, and it's almost impossible for users to tell when it happens.
<p>BTW in 2023 I watched ChatGPT spit out hundreds of lines of F# verbatim from my own GitHub. A lot of people had this experience with GitHub Copilot. "98.7% unique" is still a lot of infringement.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316393"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316393">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316142" class="clicky" aria-hidden="true">parent</a> | <a href="#47316355" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>people have legal liability and LLMs do not. You can't sue an LLM for copyright infringement</em>
<p>That's not relevant, because you can still sue the person using the LLM and publishing the repository. Legal liability is completely unchanged.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317041"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47317041">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316393" class="clicky" aria-hidden="true">parent</a> | <a href="#47316355" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;Legal liability is completely unchanged.
<p>It's changed completely, from your own example.</p>
<p>If you comission art from an artist who paints a modified copy of Warhol's work, the artist is liable (even if you keep that work private, for personal use).</p>
<p>If you commission it from OpenAI (by sending a query to their ChatGPT API), by your argument, <em>you</em> are the person liable — and OpenAI is off the hook even if that work is distributed <em>further</em>.</p>
<p>I'm not going to argue about the merits of creativity here, or that someone putting a prompt into ChatGPT considers themselves an artist.</p>
<p>That's irrelevant. The work is <em>created</em> on OpenAI servers, by the LLMs hosted there, and is then <em>distributed</em> to whoever wrote the prompt.</p>
<p>Models run locally are <em>distributed</em> by whoever trained them.</p>
<p>If you train a model on whatever data you legally have access to, and produce something <em>for yourself</em>, it's one thing.</p>
<p><em>Distribution</em> is where things start to get different.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317398"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47317398">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47317041" class="clicky" aria-hidden="true">parent</a> | <a href="#47316355" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>If you commission it from OpenAI (by sending a query to their ChatGPT API), by your argument, you are the person liable — and OpenAI is off the hook even if that work is distributed further.</em>
<p>Let's distinguish two different scenarios here:</p>
<p>1) Your prompt is copyright-free, but the LLM produces a significant amount of copyrighted content verbatim. Then the LLM is liable, and you too are liable if you redistribute it.</p>
<p>2) Your prompt contains copyrighted data, and the LLM transforms it, and you distribute it. Then if the transformation <em>is not sufficient</em>, you are liable for redistributing it.</p>
<p>The second example is what I'm referring to, since the commercial LLM's are now very good about not reproducing copyrighted content verbatim. And yes, OpenAI is off the hook from everything I understand legally.</p>
<p>Your example of commissioning an artist is different from LLM's, because the artist is legally responsible for the product and is selling <em>the result</em> to you as a <em>creative human work</em>, whereas an LLM is a software tool and the company is selling <em>access</em> to it. So the better analogy is if you rent a Xerox copier to copy something by Warhol. Xerox is not liable if you try to redistribute that copy. But you are. So here, Xerox=OpenAI. They are not liable for <em>your</em> copyrighted inputs turning into copyrighted outputs.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318372"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47318372">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47317398" class="clicky" aria-hidden="true">parent</a> | <a href="#47317692" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;So the better analogy is if you rent a Xerox copier to copy something by Warhol
<p>It isn't.</p>
<p>One analogy in that case would be going to a FedEx copy center and asking the technician to produce a bunch of copies of something.</p>
<p>They absolve themselves of liability by having you <em>sign a waiver</em> certifying that you have complete rights to the data that serves as input to the machine.</p>
<p>In case of LLMs, that includes <em>the entire training set</em>.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317692"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Copyrightest" class="hnuser">Copyrightest</a> <a href="https://news.ycombinator.com/item?id=47317692">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47317398" class="clicky" aria-hidden="true">parent</a> | <a href="#47318372" class="clicky" aria-hidden="true">prev</a> | <a href="#47316355" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The most salient difference is that it's impossible to tell if an LLM is plagiarizing, whereas Xeroxing something implies specific intent to copy. It makes no sense to push liability onto LLM users.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318177"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47318177">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47317692" class="clicky" aria-hidden="true">parent</a> | <a href="#47316355" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Are you following the distinction between my scenarios (1) and (2)?
<p>In scenario (1) the LLM is plagiarizing. <em>But that's not the scenario we're discussing.</em> And I already said, this is where the LLM is liable. Whether a user should be too is a different question.</p>
<p>But scenario (2) is what I'm discussing, as I already explained, and it's <em>very possible</em> to tell, because <em>you yourself submitted the copyrighted content</em>. All you need to do is look at whether the output is too similar to the input.</p>
<p>If there's some scenario where you input copyrighted material and it transforms it into different material that is also copyrighted <em>by someone else</em>... that is a pretty unlikely edge case.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316355"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=satvikpendem" class="hnuser">satvikpendem</a> <a href="https://news.ycombinator.com/item?id=47316355">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47316142" class="clicky" aria-hidden="true">parent</a> | <a href="#47316393" class="clicky" aria-hidden="true">prev</a> | <a href="#47315555" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can sue the company making the LLM, which is what many have done.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315555"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47315555">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">parent</a> | <a href="#47315588" class="clicky" aria-hidden="true">prev</a> | <a href="#47316956" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree there has to be a court case about it. I think the current argument, however, is that it is transformative, and therefore falls under fair use.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315822"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=munk-a" class="hnuser">munk-a</a> <a href="https://news.ycombinator.com/item?id=47315822">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315555" class="clicky" aria-hidden="true">parent</a> | <a href="#47317170" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yea, a finding that training is transformative would be pretty significant and it's likely that the precedent of thumbnail creation being deemed transformative would likely steer us towards such a finding. Transformative is always a hard thing to bank on because it is such a nebulous and judgement based call. There are excellent examples of how precise and gritty this can get in audio sampling.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315993"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47315993">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315822" class="clicky" aria-hidden="true">parent</a> | <a href="#47317170" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Didn't know about thumbnails being fair use. In that case, I just don't see an argument that genAI training on source code is less transformative than thumbnails.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317170"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jazzyjackson" class="hnuser">jazzyjackson</a> <a href="https://news.ycombinator.com/item?id=47317170">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47315555" class="clicky" aria-hidden="true">parent</a> | <a href="#47315822" class="clicky" aria-hidden="true">prev</a> | <a href="#47316956" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You don’t get to simply claim fair use based on how transformative your derivative work is.
<p>“”” Section 107 calls for consideration of the following four factors in evaluating a question of fair use:</p>
<p>Purpose and character of the use, including whether the use is of a commercial nature or is for nonprofit educational purposes: Courts look at how the party claiming fair use is using the copyrighted work, and are more likely to find that nonprofit educational and noncommercial uses are fair. This does not mean, however, that all nonprofit education and noncommercial uses are fair and all commercial uses are not fair; instead, courts will balance the purpose and character of the use against the other factors below. Additionally, “transformative” uses are more likely to be considered fair. Transformative uses are those that add something new, with a further purpose or different character, and do not substitute for the original use of the work.</p>
<p>Nature of the copyrighted work: This factor analyzes the degree to which the work that was used relates to copyright’s purpose of encouraging creative expression. Thus, using a more creative or imaginative work (such as a novel, movie, or song) is less likely to support a claim of a fair use than using a factual work (such as a technical article or news item). In addition, use of an unpublished work is less likely to be considered fair.</p>
<p>Amount and substantiality of the portion used in relation to the copyrighted work as a whole: Under this factor, courts look at both the quantity and quality of the copyrighted material that was used. If the use includes a large portion of the copyrighted work, fair use is less likely to be found; if the use employs only a small amount of copyrighted material, fair use is more likely. That said, some courts have found use of an entire work to be fair under certain circumstances. And in other contexts, using even a small amount of a copyrighted work was determined not to be fair because the selection was an important part—or the “heart”—of the work.</p>
<p>Effect of the use upon the potential market for or value of the copyrighted work: Here, courts review whether, and to what extent, the unlicensed use harms the existing or future market for the copyright owner’s original work. In assessing this factor, courts consider whether the use is hurting the current market for the original work (for example, by displacing sales of the original) and/or whether the use could cause substantial harm if it were to become widespread. “””</p>
<p><a href="https://www.copyright.gov/fair-use/" rel="nofollow">https://www.copyright.gov/fair-use/</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318366"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=NewsaHackO" class="hnuser">NewsaHackO</a> <a href="https://news.ycombinator.com/item?id=47318366">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">root</a> | <a href="#47317170" class="clicky" aria-hidden="true">parent</a> | <a href="#47316956" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;I haven't claimed anything, The courts did: <a href="https://www.whitecase.com/insight-alert/two-california-district-judges-rule-using-books-train-ai-fair-use" rel="nofollow">https://www.whitecase.com/insight-alert/two-california-distr...</a>. And regardless, my point still stands that it is an open question; however, given the already present body of cases, it is tipping in the favor of the AI companies. Also, if thumbnails fall under fair use due to it being transformative of full-sized pictures, I cannot see an argument that AI training on data is somehow less transformative than downscaling an image for a thumbnail.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316956"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=paxys" class="hnuser">paxys</a> <a href="https://news.ycombinator.com/item?id=47316956">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">parent</a> | <a href="#47315555" class="clicky" aria-hidden="true">prev</a> | <a href="#47319627" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The act of training by itself has been ruled to be fair use over and over again, including for LLMs, and there isn't much debate left there.
<p>The test for infringement is if the <em>output</em> is transformative enough, and that is what NYT vs OpenAI etc. are arguing.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319627"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=steve_gh" class="hnuser">steve_gh</a> <a href="https://news.ycombinator.com/item?id=47319627">2 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">parent</a> | <a href="#47316956" class="clicky" aria-hidden="true">prev</a> | <a href="#47312824" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is the LLM acting as my agent? If the LLM has been exposed to the source code then have I been exposed to the source code? So in that case is a "clean room" implementation possible?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312824"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=PaulDavisThe1st" class="hnuser">PaulDavisThe1st</a> <a href="https://news.ycombinator.com/item?id=47312824">3 days ago</a> | <a href="#47315401" class="clicky" aria-hidden="true">prev</a> | <a href="#47312099" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If Blanchard is claiming not to have been substantively involved in the creation of the new implementation of chardet (i.e. "Claude did it"), then the new implementation is machine generated, and in the USA cannot be copyright and thus cannot be licensed.
<p>If he is claiming to have been somehow substantively "enough" involved to make the code copyrightable, then his own familiarity with the previous LGPL implementation makes the new one almost certainly a derivative of the original.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314996"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sigmar" class="hnuser">sigmar</a> <a href="https://news.ycombinator.com/item?id=47314996">3 days ago</a> | <a href="#47312824" class="clicky" aria-hidden="true">parent</a> | <a href="#47312099" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;then his own familiarity with the previous LGPL implementation makes the new one almost certainly a derivative of the original.
<p>The "clean room rewrite" is just an extreme way to have a bulletproof shield against litigation. Not doing it that way doesn't automatically make all new code he writes derivative solely because he saw how the code worked previously.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315255"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=PaulDavisThe1st" class="hnuser">PaulDavisThe1st</a> <a href="https://news.ycombinator.com/item?id=47315255">3 days ago</a> | <a href="#47312824" class="clicky" aria-hidden="true">root</a> | <a href="#47314996" class="clicky" aria-hidden="true">parent</a> | <a href="#47312099" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If the clean room re-write was done entirely by Claude, then the result cannot be copyright in the USA, and thus there is no license at all.
<p>And if he was in fact more involved (which he appears to deny) that it's a bit weak to say that someone with huge familiarity with chardet could choose to reimplement chardet without the result being derivative.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315612"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=serial_dev" class="hnuser">serial_dev</a> <a href="https://news.ycombinator.com/item?id=47315612">3 days ago</a> | <a href="#47312824" class="clicky" aria-hidden="true">root</a> | <a href="#47315255" class="clicky" aria-hidden="true">parent</a> | <a href="#47312099" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">So if I read any LGPL code in my life, I can never think about working on something similar in my life?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315971"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vbarrielle" class="hnuser">vbarrielle</a> <a href="https://news.ycombinator.com/item?id=47315971">3 days ago</a> | <a href="#47312824" class="clicky" aria-hidden="true">root</a> | <a href="#47315612" class="clicky" aria-hidden="true">parent</a> | <a href="#47319231" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's a difference between "I've read a LGPL code once, maybe I could do something similar" and "I've been reading this LGPL code for 12 years and now I'm going to do exactly the same thing".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319231"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=heavyset_go" class="hnuser">heavyset_go</a> <a href="https://news.ycombinator.com/item?id=47319231">2 days ago</a> | <a href="#47312824" class="clicky" aria-hidden="true">root</a> | <a href="#47315612" class="clicky" aria-hidden="true">parent</a> | <a href="#47315971" class="clicky" aria-hidden="true">prev</a> | <a href="#47312099" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's a reason Windows developers are prohibited from contributing to Wine</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312099"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=largbae" class="hnuser">largbae</a> <a href="https://news.ycombinator.com/item?id=47312099">3 days ago</a> | <a href="#47312824" class="clicky" aria-hidden="true">prev</a> | <a href="#47317797" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This is only worth arguing about because software has value. Putting this in context of a world where the cost of writing code is trending to 0, there are two obvious futures:
<p>1. The cost continues to trend to 0, and _all_ software loses value and becomes immediately replaceable. In this world, proprietary, copyleft and permissive licenses do not matter, as I can simply have my AI reimplement whatever I want and not distribute it at all.</p>
<p>2. The coding cost reduction is all some temporary mirage, to be ended soon by drying VC money/rising inference costs, regulatory barriers, etc. In that world we should be reimplementing everything we can as copyleft while the inferencing is good.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312204"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sarchertech" class="hnuser">sarchertech</a> <a href="https://news.ycombinator.com/item?id=47312204">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">parent</a> | <a href="#47314989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There’s an other option. The cost of copying existing software trends to 0, but the cost of writing new software stays far enough above 0 that it is still relatively expensive.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314989"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=beepbooptheory" class="hnuser">beepbooptheory</a> <a href="https://news.ycombinator.com/item?id=47314989">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">parent</a> | <a href="#47312204" class="clicky" aria-hidden="true">prev</a> | <a href="#47312148" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There will always be cost though. Even if perfect code is getting one-shotted out, that is constantly maintained and adapted to changing conditions and technology, it simply can't <em>stay</em> at 0 forever because one day the power is surely going to go out!
<p>More and more I am drawn to these kinds of ideas lately, perhaps as a kind of ethical sidestep, but still:</p>
<p>- <a href="https://wiki.xxiivv.com/site/permacomputing.html" rel="nofollow">https://wiki.xxiivv.com/site/permacomputing.html</a></p>
<p>- <a href="https://permacomputing.net/" rel="nofollow">https://permacomputing.net/</a></p>
<p>It's not going to solve any general issue here, but the one thing these freaks <em>need</em> that can't be generated by their models is energy, tons of it. So, the one thing I can do as an individual and in my (digital) community is work to be, in a word, self-sustainable. And depending on my company I guess, if I was a CEO I would hope I was wise enough to be thinking on the same lines.</p>
<p>Everyone is making beautiful mountains from paper and wire. I will just be happy to make a small dollhouse of stone, I think it will be worth it. How can we see not just at least some small-level of hubris otherwise?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312148"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=anonymous_sorry" class="hnuser">anonymous_sorry</a> <a href="https://news.ycombinator.com/item?id=47312148">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">parent</a> | <a href="#47314989" class="clicky" aria-hidden="true">prev</a> | <a href="#47312307" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There was a recent ruling that LLM output is inherently public domain (presumably unless it infringes some existing copyright). In which case it's not possible to use them to "reimplement everything we can as copyleft".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312352"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dathinab" class="hnuser">dathinab</a> <a href="https://news.ycombinator.com/item?id=47312352">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">root</a> | <a href="#47312148" class="clicky" aria-hidden="true">parent</a> | <a href="#47324558" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">it's more complicated, the ruling was that AI can't be an author and the thing in question is (de-facto) public domain because it has no author in context of the "dev" claim it was fully build by AI
<p>but AI assisted code has an author and claiming it's AI assisted even if it is fully AI build is trivial (if you don't make it public that you didn't do anything)</p>
<p>also some countries have laws which treat it like a tool in the sense that the one who used it is the author by default AFIK</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324558"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=aoeusnth1" class="hnuser">aoeusnth1</a> <a href="https://news.ycombinator.com/item?id=47324558">2 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">root</a> | <a href="#47312148" class="clicky" aria-hidden="true">parent</a> | <a href="#47312352" class="clicky" aria-hidden="true">prev</a> | <a href="#47312307" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You could reimplement it as public domain on your machine, and then edit it by hand and copyleft your own edits.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312307"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=casey2" class="hnuser">casey2</a> <a href="https://news.ycombinator.com/item?id=47312307">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">parent</a> | <a href="#47312148" class="clicky" aria-hidden="true">prev</a> | <a href="#47320928" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The value of software has never been tied to the cost of writing it, even if you don't distribute it your still breaking the law.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312556"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=largbae" class="hnuser">largbae</a> <a href="https://news.ycombinator.com/item?id=47312556">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">root</a> | <a href="#47312307" class="clicky" aria-hidden="true">parent</a> | <a href="#47320928" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The article is proceeding from the premise that a reimplementation is legal (but evil). To help my understanding of your comment, do you mean:
<p>1. An LLM recreating a piece of software violates its copyright and is illegal, in which case LLM output can never be legally used because someone somewhere probably has a copyright on some portion of any software that an LLM could write.</p>
<p>2. You read my example as "copying a project without distributing it", vs. "having an LLM write the same functionality just for me"</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320928"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rstuart4133" class="hnuser">rstuart4133</a> <a href="https://news.ycombinator.com/item?id=47320928">2 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">parent</a> | <a href="#47312307" class="clicky" aria-hidden="true">prev</a> | <a href="#47317797" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I came here to say a similar thing.
<p>There would be no GPL if anybody could have cheaply and trivially reproduced the software for printers and Lisp machines Stallman was denied access to. There is no reason to force someone to give you the source code if takes no effort to reproduce.</p>
<p>Mind you, that isn't what happened here. The effort involved in getting a LLM to write software comes from three things: writing a clear unambiguous spec that also gives you a clean exported API, more clean unambiguous specs for the APIs you use, and a test suite the LLM can use to verify it has implemented the exported API correctly. Dan got them all for free, from the previous implementation which I'm sure included good documentation. That means his contribution to this new code consisted of little more than pressing the button.</p>
<p>Sadly, if you wrote some GPL software with excellent documentation, a thorough test suite, clean API, and implemented using well understood library the cost of creating a cleanroom reproduction has indeed gone to near zero over the past 24 months. The GPL licence is irrelevant.</p>
<p>Welcome to the brave new world.</p>
<p>PS: Sqlite keeping their test suite proprietary is looking like a prescient masterstroke.</p>
<p>PPS: The recent ruling that an API isn't copyrightable just took on a whole new dimension.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317797"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=justinclift" class="hnuser">justinclift</a> <a href="https://news.ycombinator.com/item?id=47317797">3 days ago</a> | <a href="#47312099" class="clicky" aria-hidden="true">prev</a> | <a href="#47315593" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; The dispute drew responses from two prominent figures in the open source world.
<p>Sure, but neither of those is an IP Lawyer.</p>
<p>The actual IP Lawyer who turned up and tried to engage, Richard Fontana, had his issue closed:</p>
<p><a href="https://github.com/chardet/chardet/issues/334" rel="nofollow">https://github.com/chardet/chardet/issues/334</a></p>
<p>Richard's point was this (quoted below):</p>
<p>---</p>
<p>FWIW, that case is not really relevant to what we are/were talking about here.</p>
<p>The question is whether you are truly an "author", or whether there was no (human) author.</p>
<p>The general legal consensus has been that generative AI output is not copyrightable (without some special facts of some sort, perhaps).</p>
<p>&gt; If all of this code was somehow not copyrightable because someone wrote a prompt instead of directly editing the code, that would have pretty huge implications.</p>
<p>That's exactly it. Your act of applying the MIT license with your copyright notice to code that you did not "directly edit" has enormous implications.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317850"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=RcouF1uZ4gsC" class="hnuser">RcouF1uZ4gsC</a> <a href="https://news.ycombinator.com/item?id=47317850">3 days ago</a> | <a href="#47317797" class="clicky" aria-hidden="true">parent</a> | <a href="#47315593" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't think Fontana's reasoning holds up.
<p>I think it is more like photography.</p>
<p>The case law is that a camera can't own a copyright, but a human can, even though all the pixels were produced by the camera with very little involvement at the pixel level by the human.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317965"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=waterTanuki" class="hnuser">waterTanuki</a> <a href="https://news.ycombinator.com/item?id=47317965">3 days ago</a> | <a href="#47317797" class="clicky" aria-hidden="true">root</a> | <a href="#47317850" class="clicky" aria-hidden="true">parent</a> | <a href="#47319821" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A camera doesn't use unlicensed IP from other sources to produce an image. The makers of the camera explicitly gave you a right to own the photograph taken with the parts used to assemble the camera.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319821"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ryukoposting" class="hnuser">ryukoposting</a> <a href="https://news.ycombinator.com/item?id=47319821">2 days ago</a> | <a href="#47317797" class="clicky" aria-hidden="true">root</a> | <a href="#47317850" class="clicky" aria-hidden="true">parent</a> | <a href="#47317965" class="clicky" aria-hidden="true">prev</a> | <a href="#47315593" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Actually yes, Fontana's reasoning <em>does</em> hold up, and the USSC seems to agree:
<p><a href="https://www.reuters.com/legal/government/us-supreme-court-declines-hear-dispute-over-copyrights-ai-generated-material-2026-03-02/" rel="nofollow">https://www.reuters.com/legal/government/us-supreme-court-de...</a></p>
<p>Prompting generally does not constitute authorship under US law.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322404"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=RcouF1uZ4gsC" class="hnuser">RcouF1uZ4gsC</a> <a href="https://news.ycombinator.com/item?id=47322404">2 days ago</a> | <a href="#47317797" class="clicky" aria-hidden="true">root</a> | <a href="#47319821" class="clicky" aria-hidden="true">parent</a> | <a href="#47315593" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That was not what the USSC case was about. It was about assigning copyright to an AI instead of a human.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315593"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=foresto" class="hnuser">foresto</a> <a href="https://news.ycombinator.com/item?id=47315593">3 days ago</a> | <a href="#47317797" class="clicky" aria-hidden="true">prev</a> | <a href="#47312660" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">From the article:
<p>&gt; He fed only the API and the test suite to Claude and asked it to reimplement the library from scratch.</p>
<p>From GPL2:</p>
<p>&gt; The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable.</p>
<p>Is a project's test suite not considered part of its source code? When I make modifications to a project, its test cases are very much a part of that process.</p>
<p>If the test suite is part of this library's source code, and Claude was fed the test suite or interface definition files, is the output not considered a <em>work based on the library</em> under the terms of LGPL 2.1?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315744"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47315744">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">parent</a> | <a href="#47315708" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's transformative, so no.
<p>Legally, using the tests to help create the reimplementation is fine.</p>
<p>However, it seems possible you can't <em>redistribute</em> the same tests under the MIT license. So the reimplementation MIT distribution could need to be source code only, not source code plus tests. Or, the tests can be distributed in parallel but still under LGPL, not MIT. It doesn't really matter since compiled software won't be including the tests anyways.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315929"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=foresto" class="hnuser">foresto</a> <a href="https://news.ycombinator.com/item?id=47315929">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47315744" class="clicky" aria-hidden="true">parent</a> | <a href="#47315708" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; It's transformative, so no.
<p>I'm not following your logic there, and I don't see any mention of "transformative" in the license. Can you explain what you mean?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316356"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316356">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47315929" class="clicky" aria-hidden="true">parent</a> | <a href="#47315708" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sorry, I misspoke. Transformation is what makes the <em>LLM itself</em> legal -- its training data is sufficiently transformed into weights.
<p>And so, a work being sufficiently transformative is one way in which copyright no longer applies, but that's not the case here specifically. The specific case here is essentially just a <em>clean-room reimplementation</em> (though technically less "clean", but still presumably the same legally). But the end result is still a completely different expression of underlying non-copyrightable ideas.</p>
<p>And in both cases, it doesn't matter <em>what</em> the original license was. If a resulting work is sufficiently transformative <em>or</em> a reimplementation, copyright no longer applies, so the license no longer applies.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316619"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=foresto" class="hnuser">foresto</a> <a href="https://news.ycombinator.com/item?id=47316619">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47316356" class="clicky" aria-hidden="true">parent</a> | <a href="#47315708" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's interesting, but it misses my point:
<p>The library's test suite and interfaces were apparently used directly, not transformed. If either of those are considered part of the library's source code, as the license's wording seems to suggest, then I think output from their use could be considered a <em>work based on the library</em> as defined in the license.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316710"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47316710">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47316619" class="clicky" aria-hidden="true">parent</a> | <a href="#47316740" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Legally that's been established as acceptable.
<p>Google LLC v Oracle America assumed (though didn't establish) that API's are copyrightable... BUT that developing against them <em>falls under fair use</em>, as long as the function implementations are independent.</p>
<p>Test suites are again generally considered copyrightable... but the <em>behavior being tested is not</em>.</p>
<p>So no, it's not considered to be a work based on the library. This seems pretty clear-cut in US law by now.</p>
<p>Also, the LGPL text doesn't say "work based on the library". It says "If you modify a copy of the Library", and this is not a "combined work" either. And the whole point is that this is not a modified copy -- it's a reimplementation.</p>
<p><em>In theory</em>, a license <em>could</em> be written to prevent running its tests from being run against software not derived from the original, i.e. clean-room reimplementations. In practice, it remains dubious whether any court would uphold that. And it would also be trivial to then get around it, by taking advantage of fair use to re-implement the tests in e.g. plain English (or any specification language), and then re-implementing those back into new test code. Because again, test <em>behaviors</em> are not copyrightable.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319208"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=heavyset_go" class="hnuser">heavyset_go</a> <a href="https://news.ycombinator.com/item?id=47319208">2 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47316710" class="clicky" aria-hidden="true">parent</a> | <a href="#47317019" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>Google LLC v Oracle America assumed (though didn't establish) that API's are copyrightable... BUT that developing against them falls under fair use, as long as the function implementations are independent.</em>
<p>That was only one prong of the four fair use considerations in that case. Look at Breyer's opinion, it does not say that copying APIs is fair use if implementations are independent, just that Google's specific usage in that instance met the four fair use considerations.</p>
<p>There are likely situations in which copying APIs is not fair use even if function implementations are independent, Breyer looked at substantiality of the code copied from Java, market effects and purpose and character of use.</p>
<p>If your goal is to copy APIs, and those APIs make up a substantial amount of code, and reimplement functions in order to skirt licenses and compete directly against the source work, or replace it, those three considerations might not be met and it might not be fair use. Breyer said Google copied a tiny fraction of code (&lt;1%), its purpose was not to compete directly with Oracle but to build a mobile OS platform, and Google's reimplementation was not considered a replacement for Java.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317019"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=foresto" class="hnuser">foresto</a> <a href="https://news.ycombinator.com/item?id=47317019">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47316710" class="clicky" aria-hidden="true">parent</a> | <a href="#47319208" class="clicky" aria-hidden="true">prev</a> | <a href="#47316740" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Also, the LGPL text doesn't say "work based on the library".
<p>It does, about a dozen times.</p>
<p>Are you perhaps referring to LGPL3? I think the license under discussion here is LGPL2.1.</p>
<p><a href="https://github.com/chardet/chardet/blob/6.0.0/LICENSE" rel="nofollow">https://github.com/chardet/chardet/blob/6.0.0/LICENSE</a></p>
<p>I'm not well versed in copyright case law, so I won't argue with the rest of what you wrote. Thanks for elaborating on your thoughts.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317212"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crazygringo" class="hnuser">crazygringo</a> <a href="https://news.ycombinator.com/item?id=47317212">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47317019" class="clicky" aria-hidden="true">parent</a> | <a href="#47316740" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oh sorry, I was indeed looking at the newer LGPL version. I stand corrected, thanks! But yes, all the same points stand. Good discussion!</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316740"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=GardenLetter27" class="hnuser">GardenLetter27</a> <a href="https://news.ycombinator.com/item?id=47316740">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47316619" class="clicky" aria-hidden="true">parent</a> | <a href="#47316710" class="clicky" aria-hidden="true">prev</a> | <a href="#47315708" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">But the tests were transformed to the new language, they are not copied as-is.
<p>Software patents would work as you describe, but not copyright.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315708"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tty456" class="hnuser">tty456</a> <a href="https://news.ycombinator.com/item?id=47315708">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">parent</a> | <a href="#47315744" class="clicky" aria-hidden="true">prev</a> | <a href="#47312660" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">Google v. Oracle ruled that use of APIs are fair game and could be argued that test cases are strictly a use of APIs and not implementation.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315802"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vbarrielle" class="hnuser">vbarrielle</a> <a href="https://news.ycombinator.com/item?id=47315802">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">root</a> | <a href="#47315708" class="clicky" aria-hidden="true">parent</a> | <a href="#47312660" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Google vs Oracle ruled that APIs fall under copyright (the contrary was thought before). However, it was ruled that, in that specific case, fair use applied, because of interoperability concerns. That's the important part of this case: fair use is never automatic, it is assessed case by case.
<p>Regarding chardet, I'm not sure "I wanted to circumvent the license" is a good way to argue fair use.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312660"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ticulatedspline" class="hnuser">ticulatedspline</a> <a href="https://news.ycombinator.com/item?id=47312660">3 days ago</a> | <a href="#47315593" class="clicky" aria-hidden="true">prev</a> | <a href="#47321316" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Surprised they don't mention Google LLC v. Oracle America, Inc. Seems a bit myopic to condone the general legality while arguing "you can only use it how I like it".
<p>It also doesn't talk about the far more interesting philosophical queston. Does what Blanchard did cover ALL implementations from Claude? What if anyone did exactly what he did, feed it the test cases and say "re-implement from scratch", ostensibly one would expect the results to be largely similar (technically under the right conditions deterministically similar)</p>
<p>could you then fork the project under your own name and a commercial license? when you use an LLM like this, to basically do what anyone else could ask it to do how do you attach any license to it? Is it first come first serve?</p>
<p>If an agent is acting mostly on its own it feels like if you found a copy of Harry Potter in the fictional library of Babel, you didn't write it, just found it amongst the infinite library, but if you found it first could you block everyone else that stumbles on a near-identical copy elsewhere in the library? or does each found copy represent a "Re-implementation" that could be individually copyrighted?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321316"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=rob74" class="hnuser">rob74</a> <a href="https://news.ycombinator.com/item?id=47321316">2 days ago</a> | <a href="#47312660" class="clicky" aria-hidden="true">prev</a> | <a href="#47311957" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; <em>Blanchard's account is that he never looked at the existing source code directly. He fed only the API and the test suite to Claude and asked it to reimplement the library from scratch. The resulting code shares less than 1.3% similarity with any prior version, as measured by JPlag. His conclusion: this is an independent new work, and he is under no obligation to carry forward the LGPL. Mark Pilgrim, the library's original author, opened a GitHub issue to object. The LGPL requires that modifications be distributed under the same license, and a reimplementation produced with ample exposure to the original codebase cannot, in Pilgrim's view, pass as a clean-room effort.</em>
<p>Another question which as far as I can see isn't addressed in the article: even if you accept that the AI-driven reimplementation is an independent new work, can you (even as a maintainer) simply "hijack" the old LGPL-licensed project and overwrite it (if the new code is 98,7% different from the existing code, it's essentially overwriting) with your MIT-licensed code? You're free to start a new MIT-licensed project with your reimplementation, but putting the new code into the old project like some kind of cuckoo's egg seems wrong to me...</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311957"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=drnick1" class="hnuser">drnick1</a> <a href="https://news.ycombinator.com/item?id=47311957">3 days ago</a> | <a href="#47321316" class="clicky" aria-hidden="true">prev</a> | <a href="#47315992" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It should be noted that the Rust community is also guilty of something similar. That is, porting old GPL programs, typically written in C, to Rust and relicensing them as MIT.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314422"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wolvesechoes" class="hnuser">wolvesechoes</a> <a href="https://news.ycombinator.com/item?id=47314422">3 days ago</a> | <a href="#47311957" class="clicky" aria-hidden="true">parent</a> | <a href="#47317479" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; porting old GPL programs, typically written in C, to Rust and relicensing them as MIT
<p>Everything for memory safety.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317479"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=phendrenad2" class="hnuser">phendrenad2</a> <a href="https://news.ycombinator.com/item?id=47317479">3 days ago</a> | <a href="#47311957" class="clicky" aria-hidden="true">parent</a> | <a href="#47314422" class="clicky" aria-hidden="true">prev</a> | <a href="#47318801" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">And BSD drivers are "clean-room reimplementations" of the GPL drivers from Linux (but we all know they aren't).</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318801"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bananamogul" class="hnuser">bananamogul</a> <a href="https://news.ycombinator.com/item?id=47318801">2 days ago</a> | <a href="#47311957" class="clicky" aria-hidden="true">parent</a> | <a href="#47317479" class="clicky" aria-hidden="true">prev</a> | <a href="#47315992" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">...and the main distros are enthusiastically adopting them.
<p>Within a relatively short time frame, expect everything in your Linux distro other than the kernel to be MIT-licensed because everything that is FSF-maintained will be rewritten in Rust with the MIT license.</p>
<p>The kernel will then be next, though it'll take a longer timeframe.</p>
<p>The GPL just didn't win in the marketplace of ideas.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320384"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wolvesechoes" class="hnuser">wolvesechoes</a> <a href="https://news.ycombinator.com/item?id=47320384">2 days ago</a> | <a href="#47311957" class="clicky" aria-hidden="true">root</a> | <a href="#47318801" class="clicky" aria-hidden="true">parent</a> | <a href="#47315992" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">People criticized Stallman et al. for being ideological, but popularity of permissive licenses is actually pure ideology, in Marxian sense - people doing without knowing, and conflating their interests with interests of big capital. You can see the same with people defending AI-laundering.
<p>Stallman's proposal is opposite of ideology, it is <em>conscious</em> political project. And thus it is failing.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315992"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lukev" class="hnuser">lukev</a> <a href="https://news.ycombinator.com/item?id=47315992">3 days ago</a> | <a href="#47311957" class="clicky" aria-hidden="true">prev</a> | <a href="#47311632" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree with the thrust of this article, that norms and what we perceive as good or desirable extend considerably beyond the minimum established by law.
<p>But a point that was not made strongly, which highlights this even more, is that this goes in <em>every direction</em>.</p>
<p>If this kind of reimplementation is legal, then I can take any permissive OSS and rebuild it as proprietary. I can take any proprietary software and rebuild it as permissive. I can take any proprietary software and rebuild it as my <em>own</em> proprietary software.</p>
<p>Either the law needs to catch up and prevent this kind of behavior, or we're going to enter an effectively post-copyright world with respect to software. Which ISN'T GOOD, because that will disincentivize any sort of open license at all, and companies will start protecting/obfuscating their APIs like trade secrets.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316113"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=integralid" class="hnuser">integralid</a> <a href="https://news.ycombinator.com/item?id=47316113">3 days ago</a> | <a href="#47315992" class="clicky" aria-hidden="true">parent</a> | <a href="#47316363" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It goes in one direction only.
<p>Companies can take open-source software and make a proprietary reimplementation. You can't take a proprietary software and make an open source GPL version.</p>
<p>I am absolutely certain that if you tried you would be sued to oblivion. But big company screwing up open source is not even news anymore. In fact I (still) believe that the fact that even though LLMs were trained on tons of GPL and AGPL or even unlicensed software it's considered ok to use LLM code in proprietary projects is example of just that.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316167"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=lukev" class="hnuser">lukev</a> <a href="https://news.ycombinator.com/item?id=47316167">3 days ago</a> | <a href="#47315992" class="clicky" aria-hidden="true">root</a> | <a href="#47316113" class="clicky" aria-hidden="true">parent</a> | <a href="#47316363" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">From a strictly legal perspective the two are equivalent. The fact that there are structural injustices in the system is true, but that's not a question that any answer to "what should be legal" can fix.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316363"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47316363">3 days ago</a> | <a href="#47315992" class="clicky" aria-hidden="true">parent</a> | <a href="#47316113" class="clicky" aria-hidden="true">prev</a> | <a href="#47311632" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I've been thinking this for over two years, that's why I stopped contributing to open source at that time - my work was only gonna be exploited to make rich people richer regardless of the license.
<p>Crazy that only now we're seeing a bunch of articles coming to the same conclusion now.</p>
<p>I think copyright should still apply, but if it doesn't, we need new laws - ones which protect all human work, creative or not. Laws should serve and protect people, not algorithms and not corporations "owning" those algorithms.</p>
<p>I put owning in quotes because ownership should go to the people who did the work.</p>
<p>Buying/selling ownership of both companies and people's work should be illegal just like buying/selling whole humans is. Even if it took thousands of years to get here.</p>
<p>Money should not buy certain things because this is the root cause of inequality. Rich people are not getting richer at a faster rate by being more productive than everyone else but by "owning" other people's work and using it as leverage to extract even more from others.</p>
<p>Maybe LLM and mass unemployment of white collar workers will be the wakeup call needed for a reform. Or revolution.</p>
<p>Last time this happened was during the second industrial revolution and that's how communism got popular. We should do better this time because this is the last revolution which might be possible.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311632"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wccrawford" class="hnuser">wccrawford</a> <a href="https://news.ycombinator.com/item?id=47311632">3 days ago</a> | <a href="#47315992" class="clicky" aria-hidden="true">prev</a> | <a href="#47315989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"Antirez closes his careful legal analysis as though it settles the matter. Ronacher acknowledges that “there is an obvious moral question here, but that isn't necessarily what I'm interested in.” Both pieces treat legal permissibility as a proxy for social legitimacy. "
<p>This whole article is just complaining that other people didn't have the discussion he wanted.</p>
<p>Ronacher even acknowledged that it's a different discussion, and not one they were trying to have at the moment.</p>
<p>If you want to have it, have it. Don't blast others for <em>not</em> having it for you.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311817"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wizzwizz4" class="hnuser">wizzwizz4</a> <a href="https://news.ycombinator.com/item?id=47311817">3 days ago</a> | <a href="#47311632" class="clicky" aria-hidden="true">parent</a> | <a href="#47315989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Having this discussion <em>involves</em> blasting others for not considering it. Consider the rest of the paragraph you quoted:
<p>&gt; But law only says what conduct it will not prevent—it does not certify that conduct as right. Aggressive tax minimization that never crosses into illegality may still be widely regarded as antisocial. A pharmaceutical company that legally acquires a patent on a long-generic drug and raises the price a hundredfold has not done something legal and therefore fine. Legality is a necessary condition; it is not a sufficient one.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312536"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=amarant" class="hnuser">amarant</a> <a href="https://news.ycombinator.com/item?id=47312536">3 days ago</a> | <a href="#47311632" class="clicky" aria-hidden="true">root</a> | <a href="#47311817" class="clicky" aria-hidden="true">parent</a> | <a href="#47315989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If the discussion inherently cannot be had without blasting innocent bystanders, I don't think it's a discussion worth having.
<p>It might even be morally abhorrent to have such a discussion in the first place!</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324968"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wizzwizz4" class="hnuser">wizzwizz4</a> <a href="https://news.ycombinator.com/item?id=47324968">2 days ago</a> | <a href="#47311632" class="clicky" aria-hidden="true">root</a> | <a href="#47312536" class="clicky" aria-hidden="true">parent</a> | <a href="#47315989" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">They're not innocent bystanders: if you take the premise of the article seriously, their actions should be criticised. Please consider re-reading the article more slowly.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315989"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=miggol" class="hnuser">miggol</a> <a href="https://news.ycombinator.com/item?id=47315989">3 days ago</a> | <a href="#47311632" class="clicky" aria-hidden="true">prev</a> | <a href="#47312573" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Wow, it feels like this argument rewired my brain.
<p>When I first read about the chardet situation, I was conflicted but largely sided on the legal permissibility side of things. Uncomfortably I couldn't really fault the vibers; I guess I'm just liberal at heart.</p>
<p>The argument from the commons has really invoked my belief in the inherent morality of a public good. Something being "impermissible" sounds bad until you realize that otherwise the arrow of public knowledge suddenly points backwards.</p>
<p>Seeing this example play out in real life has had retroactive effects on my previously BSD-aligned brain. Even though the argument itself may have been presented before, I now understand the morals that a GPL license text underpins better.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317247"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=crdrost" class="hnuser">crdrost</a> <a href="https://news.ycombinator.com/item?id=47317247">3 days ago</a> | <a href="#47315989" class="clicky" aria-hidden="true">parent</a> | <a href="#47312573" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">FWIW I like to explain it to folks like this: ignore all of your moral baggage around licensing and just focus on the fact that licensing is a legal tool of art that pretty much only becomes relevant in the context of threatening lawsuits.
<p>BSD-type stuff is very simple because it says "here is this stuff. you can use it as long as you promise not to sue me. I promise not to sue you too."</p>
<p>Very simple.</p>
<p>GPL-type stuff is intrinsically more complex because it's trying to use the threatening power of lawsuits, to reduce overall IP lawsuits. So it has to say "Here is this stuff. You can use it as long as you promise not to sue me. I am only going to sue you, if you start pretending like you have the right to sue other folks over this stuff or anything you derive from it. You don't have the right to sue others for it, I made it, so please stop pretending and let's stop suing each other over this sort of thing."</p>
<p>Getting the entire legal nuance around that sort of counterfactual "I will only sue you if you try to pretend that you can sue others" is why they're more complex. And the simplest copyleft licenses like the Mozilla Public License have a very rigid notion of what "the software" is, so like for MPL it's "this file is gonna never be used in a lawsuit, you can edit it ONLY as long as you agree that this file must never be used by you to sue someone else, if you try to mutate it in a way that lets you sue someone else then that's against our agreement and we reserve the right to sue you."</p>
<p>Whereas for GPL it's actually kind of nebulous what "the software" is -- everything that feeds into the eventual compiled binary, basically -- and so the license itself needs to be a little bit airy-fairy, "let's first talk about what conveying the software means...", in various ways.</p>
<p>The interesting thing here is that as far as the courts are initially ruling, these from-scratch reimplementations are not human works and therefore are not copyrightable, which makes them all kind of public domain. Slapping the MIT license on it was an overstep. If that's how things go then Free Software has actually won its greatest sweep with LLM ubiquity.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318595"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=derangedHorse" class="hnuser">derangedHorse</a> <a href="https://news.ycombinator.com/item?id=47318595">2 days ago</a> | <a href="#47315989" class="clicky" aria-hidden="true">root</a> | <a href="#47317247" class="clicky" aria-hidden="true">parent</a> | <a href="#47312573" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm sure they wouldn't mind marking it as public domain. MIT is just the go-to license for things like this since it forces other people to notify others it came from an MIT repo if substantial parts of the original repo was used.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312573"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ineedasername" class="hnuser">ineedasername</a> <a href="https://news.ycombinator.com/item?id=47312573">3 days ago</a> | <a href="#47315989" class="clicky" aria-hidden="true">prev</a> | <a href="#47312203" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This article is setting up a bit of a moving target. Legal vs legitimate is at least only a single vague question to be defined but then the target changes to “socially legitimate” defined only indirectly by way of example, like aggressive tax avoidance as “antisocial”— and while I tend to agree with that characterization my agreement is predicated on a layering of other principals.
<p>The fundamental problem is that once you take something outside the realm of law and rule of law in its many facets as the legitimizing principal, you have to go a whole lot further to be coherent and consistent.</p>
<p>You can’t just leave things floating in a few ambiguous things you don’t like and feel “off” to you in some way- not if you’re trying to bring some clarity to your own thoughts, much less others. You don’t <em>have to land on a conclusion</em> either. By all means chew over things, but once you try to settle, things fall apart if you haven’t done the harder work of replacing the framework of law with that of another conceptual structure.</p>
<p>You need to at least be asking “to what ends? What purpose is served by the rule?” Otherwise you’re stuck in things where half the time you end up arguing backwards in ways that put purpose serving rules, the maintenance of the rule with justifications ever further afield pulled in when the rule is questioned and edge cases reached. If you’re asking, essentially, “is the spirit of the rule still there?” You’ve got to stop and fill in what that spirit is or you or people that want to control you or have an agenda will sweep in with their own language and fill the void to their own ends.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312203"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=skybrian" class="hnuser">skybrian</a> <a href="https://news.ycombinator.com/item?id=47312203">3 days ago</a> | <a href="#47312573" class="clicky" aria-hidden="true">prev</a> | <a href="#47313320" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Broadly speaking, the “freedom of users” is often protected by competition from competing alternatives. The GNU command line tools were replacements for system utilities. Linux was was a replacement for other Unix kernels. People chose to install them instead of proprietary alternatives. Was it due to ideology or lower cost or more features? All of the above. Different users have different motivations.
<p>Copyleft could be seen as an attempt to give Free Software an edge in this competition for users, to counter the increased resources that proprietary systems can often draw on. I think success has been mixed. Sure, Linux won on the server. Open source won for libraries downloaded by language-specific package managers. But there’s a long tail of GPL apps that are not really all that appealing, compared to all the proprietary apps available from app stores.</p>
<p>But if reimplementing software is easy, there’s just going to be a lot more competition from both proprietary and open source software. Software that you can download for free that has better features and is more user-friendly is going to have an advantage.</p>
<p>With coding agents, it’s likely that you’ll be able to modify apps to your own needs more easily, too. Perhaps plugin systems and an AI that can write plugins for you will become the norm?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312245"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jacquesm" class="hnuser">jacquesm</a> <a href="https://news.ycombinator.com/item?id=47312245">3 days ago</a> | <a href="#47312203" class="clicky" aria-hidden="true">parent</a> | <a href="#47313320" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Was it due to ideology or lower cost or more features?
<p>It was due to <em>access</em>.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313320"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=AndriyKunitsyn" class="hnuser">AndriyKunitsyn</a> <a href="https://news.ycombinator.com/item?id=47313320">3 days ago</a> | <a href="#47312203" class="clicky" aria-hidden="true">prev</a> | <a href="#47322415" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's a Japanese version of that page, written in classical text writing direction, in columns. Which is cool. Makes me wonder, though - how readable is it with so many English loanwords which should be rotated sideways to fit into columns?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313598"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ddellacosta" class="hnuser">ddellacosta</a> <a href="https://news.ycombinator.com/item?id=47313598">3 days ago</a> | <a href="#47313320" class="clicky" aria-hidden="true">parent</a> | <a href="#47322415" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Total digression but yeah, that layout is stupid and the way those words are dropped in using Romaji makes no sense. That's not how Japanese people lay out pages on the web. In fact I don't think I've ever seen a Japanese web page laid out like a book like this, and in general I'd expect the English proper nouns and words that don't have obvious translations to get transliterated into Katakana. Smells like automatic conversion added by someone not really familiar with common practices for presenting Japanese on the web.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315897"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tmp10423288442" class="hnuser">tmp10423288442</a> <a href="https://news.ycombinator.com/item?id=47315897">3 days ago</a> | <a href="#47313320" class="clicky" aria-hidden="true">root</a> | <a href="#47313598" class="clicky" aria-hidden="true">parent</a> | <a href="#47322415" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">He also has a Korean vertical layout that lays out Latin-character words the same way. Is this common in Korea when vertical layout is used? The author seems to be Korean.
<p>Looks like Wikipedia has an example of Traditional Chinese vertical layout with the Latin letters rotated as in TFA's layout (<a href="https://en.wikipedia.org/wiki/Horizontal_and_vertical_writing_in_East_Asian_scripts#/media/File:Hebei_Wen'an_jin_fasheng_dizhen_-_Beijing_you_zhengan.png" rel="nofollow">https://en.wikipedia.org/wiki/Horizontal_and_vertical_writin...</a>)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322415"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=orthoxerox" class="hnuser">orthoxerox</a> <a href="https://news.ycombinator.com/item?id=47322415">2 days ago</a> | <a href="#47313320" class="clicky" aria-hidden="true">prev</a> | <a href="#47312198" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">One thing I don't understand is what was so bad about having an LGPL license. You are allowed to do `import chardet` in a MIT-licensed or a proprietary program.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324044"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=spiffyk" class="hnuser">spiffyk</a> <a href="https://news.ycombinator.com/item?id=47324044">2 days ago</a> | <a href="#47322415" class="clicky" aria-hidden="true">parent</a> | <a href="#47312198" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That is also my understanding. My personal theory is that many corporate compliance departments (or whoever is in charge of this at a particular place) just disallow any *GPL use in their company, regardless of whether it would actually cause problems, so this is an attempt to "unblock" the library for those. Instead of, you know, educating people about the nuances of different copyleft licenses.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47332949"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=orthoxerox" class="hnuser">orthoxerox</a> <a href="https://news.ycombinator.com/item?id=47332949">1 day ago</a> | <a href="#47322415" class="clicky" aria-hidden="true">root</a> | <a href="#47324044" class="clicky" aria-hidden="true">parent</a> | <a href="#47312198" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Perhaps you are right. I work for a company right now that has a smarter than average legal4IT department and they ask sensible questions about every piece of FLOSS code you want to bring in:
<pre><code>   - what is the license?
   - is it a program or a library?
   - do you plan to use it as-is or modify it?
   - do you plan to include it in our products or is it for internal use only?
</code></pre>
But I have also worked for a company that simply had "if MIT, BSD, Apache, ISC, MPL, zlib then OK else notOK" as a policy.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312198"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kazinator" class="hnuser">kazinator</a> <a href="https://news.ycombinator.com/item?id=47312198">3 days ago</a> | <a href="#47322415" class="clicky" aria-hidden="true">prev</a> | <a href="#47317446" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You can't put a copyright and MIT license on something you generated with AI. It is derived from the work of many unknown, uncredited authors.
<p>Think about it; the license says that copies of the work must be reproduced with the copyright notice and licensing clauses intact. Why would anyone obey that, knowing it came from AI?</p>
<p>Countless instances of such licenses were ignored in the training data.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314999"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=harshreality" class="hnuser">harshreality</a> <a href="https://news.ycombinator.com/item?id=47314999">3 days ago</a> | <a href="#47312198" class="clicky" aria-hidden="true">parent</a> | <a href="#47314406" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">When learning is sufficiently atomized and recombined, creations cease to be "derived from" in a legal sense.
<p>A lego sculpture is copyrighted. Lego blocks are not. The threshold between blocks and sculpture is not well-defined, but if an AI isn't prompted specifically to attempt to mimic an existing work, its output will be safely on the non-copyrighted side of things.</p>
<p>A derivative work is separately copyrightable, but redistribution needs permission from the original author too. Since that usually won't be granted or would be uneconomical, the derivative work can't usually be redistributed.</p>
<p>AI-produced material is inherently not copyrightable, but not because it's a derivative work.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315628"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kazinator" class="hnuser">kazinator</a> <a href="https://news.ycombinator.com/item?id=47315628">3 days ago</a> | <a href="#47312198" class="clicky" aria-hidden="true">root</a> | <a href="#47314999" class="clicky" aria-hidden="true">parent</a> | <a href="#47314406" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Token prediction is a form of "learning" that is reinforced by the goal of reproducing the correct next token of the work, rather that acquiring ideas and concepts. For instance, given the prefix "Four score and seven years", the weights are adjusted until "ago" is correctly predicted, which is a fancy way of saying that it was stored in the model in a lossy way. The model "learned" that "ago" follows "four score and seven years" exactly the way your hard drive "learns" the audio and video frames of a movie when you download a .mp4 file.
<p>I dispute the idea that token sequences reproduced from the model are not derived works.</p>
<p>I predict, no pun intended, that a time is coming when the idea that it's not a derived work will be challenged in mainstream law.</p>
<p>The slop merchants are getting a free ride for the time being.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316868"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=harshreality" class="hnuser">harshreality</a> <a href="https://news.ycombinator.com/item?id=47316868">3 days ago</a> | <a href="#47312198" class="clicky" aria-hidden="true">root</a> | <a href="#47315628" class="clicky" aria-hidden="true">parent</a> | <a href="#47314406" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Only because that quote is famous.
<p>As you said, it's lossy. Try it with any other distinctive but non-famous passage, and you won't get a correct prediction for the immediately following clause, much less for multiple sentences or paragraphs.</p>
<p>That's the case <em>even when an LLM correctly identifies which book the prompted text is from.</em> It still won't accurately continue on from some arbitrary passage. By the time you ask it to reproduce hundreds of words, you're into brand new book territory. Even when it's slop content, it's distinct slop.</p>
<p>The exceptions are cases where a significant number of humans would also know a particular quote from memory. Then, chances are, a frontier LLM will too.</p>
<p>You know how else you can reproduce a quote? Search for it on google, and search the resulting top hits; if it's a significant quote, multiple people have probably quoted it -- <em>legally</em>. You can also search a pirate library for the actual book, and search the book for the quote; while illegal, it's very simple to do, so unless you propose to make the free and open internet illegal, I'd suggest that banning LLMs for being "derivative work" creation engines is not so different from destroying the internet.</p>
<p>&gt; I predict, no pun intended, that a time is coming when the idea that it's not a derived work will be challenged in mainstream law.</p>
<p>If judges have any sense whatsoever, LLM generations (without specific prompt crafting to mimic existing works) will be judged to not be derived works and therefore not be violating copyright, in the same sense that you can live and breathe Taylor Swift's music, create new music in the same style, and still not be violating copyright.</p>
<p>The Stability AI case, and how Judge Orrick deals with it, will be interesting and uninteresting at the same time. It deals primarily with the fact that after <em>specific prompting</em>, an image-generation AI can generate something fairly close to existing copyrighted images. That doesn't say anything more about whether LLMs are inherently producers of [only or primarily] derivative works, just as the fact that a human can violate copyright doesn't say anything about whether humans primarily or exclusively output derivative works.</p>
<p>More likely, perhaps, is that everything will be so infused with LLM output that copyright ceases to be relevant, or forces copyright law to be rewritten from the ground up.</p>
<p>Copyright requirements, even prior to LLMs, weren't well-specified. There's no objective threshold for how close something has to be to a previous work before the new one violates copyright. It's whatever a judge thinks, refering to the 4-factor test but ultimately making subjective judgements about each of those prongs. It's all a house of cards, and LLMs may just be what topples it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47326498"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kazinator" class="hnuser">kazinator</a> <a href="https://news.ycombinator.com/item?id=47326498">2 days ago</a> | <a href="#47312198" class="clicky" aria-hidden="true">root</a> | <a href="#47316868" class="clicky" aria-hidden="true">parent</a> | <a href="#47314406" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Machine translations do not contain a literal quote of the source material, yet are covered by copyright. For instance, binary executables do not quote the source code.
<p>I predict that the LLM will be regarded as a binary-like machine translation of the source materials.</p>
<p>Lossiness is a red herring. You can't claim that a JPEG photograph doesn't violate copyright because JPEG is lossy.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314406"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=moralestapia" class="hnuser">moralestapia</a> <a href="https://news.ycombinator.com/item?id=47314406">3 days ago</a> | <a href="#47312198" class="clicky" aria-hidden="true">parent</a> | <a href="#47314999" class="clicky" aria-hidden="true">prev</a> | <a href="#47317446" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Courts have already ruled that AI-generated work belongs to the public domain. So, even the MIT license does not apply.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317446"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=effank" class="hnuser">effank</a> <a href="https://news.ycombinator.com/item?id=47317446">3 days ago</a> | <a href="#47312198" class="clicky" aria-hidden="true">prev</a> | <a href="#47319449" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">My view is that the current discourse surrounding AI reimplementation is trapped in an antiquated, atomistic model of authorship. What is fundamentally lacking in this debate is a systemic framework for trust, transparency, and the effective traceability of value creation.
<p>Our legal and ethical frameworks including both copyleft and permissive licenses operate under the illusion of discrete, bounded attribution. They assume we can draw a clean perimeter around 'the code' and its 'author.' In reality, software production is a highly complex socio-technical network characterized by deep epistemic opacity. We are arguing over who holds the title to the final output while completely ignoring the vast, distributed network of inputs that made it possible.</p>
<p>Furthermore, because end-users face massive transaction costs and a general lack of incentive to evaluate the granular utility of their consumption, we have no reliable market mechanism to signal value back up the supply chain. Consequently, we fail to effectively compensate the true chain of biological and artificial contributors that facilitate downstream consumption.</p>
<p>In a rigorously mapped value-system, attribution would not stop at the keyboard; it would extend to all nodes of enablement. This includes what sociologists and economists term 'reproductive labor' or 'invisible labor' such as the developer’s partner who cooked them breakfast, thereby sustaining the biological and cognitive infrastructure necessary for the developer to contribute to the repository in the first place. The AI model is merely another node of aggregated external labor in this exact same web - both by its upward 'training' and downward utilization.</p>
<p>Until we develop an economic and technological ontology capable of tracing and rewarding this entire ecosystem of adjacent contributions, our debates over LGPL versus MIT will remain myopic. We are trying to govern a distributed, interconnected web of collective labor using property tools designed for solitary craftsmen.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319449"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=waterproof" class="hnuser">waterproof</a> <a href="https://news.ycombinator.com/item?id=47319449">2 days ago</a> | <a href="#47317446" class="clicky" aria-hidden="true">prev</a> | <a href="#47317604" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You ask Gemini to make an Elsa and Anna Frozen-themed coloring book page. It says no, that would be copyright infringement. So you ask it to make something <em>as close as possible but without infringing</em>. It happily obliges.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317604"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=joshjob42" class="hnuser">joshjob42</a> <a href="https://news.ycombinator.com/item?id=47317604">3 days ago</a> | <a href="#47319449" class="clicky" aria-hidden="true">prev</a> | <a href="#47319425" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">"If you distribute modified code, or offer it as a networked service, you must make the source available under the same terms. This is not a restriction on sharing. It is a condition placed on sharing: if you share, you must share in kind." -- This is, on any plain reading, a restriction on sharing. "You can share only under these conditions" is plainly more restrictive than "sure do whatever you want". You can argue that it's a restriction that ultimately leads to more sharing overall. But it is a restriction on sharing in any given case of sharing nevertheless.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318606"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=duskdozer" class="hnuser">duskdozer</a> <a href="https://news.ycombinator.com/item?id=47318606">2 days ago</a> | <a href="#47317604" class="clicky" aria-hidden="true">parent</a> | <a href="#47319303" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's just considering "sharing" or "freedom" out an extra step. "Total freedom" results in freedom for those who can protect it and no freedom for those who can't.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319303"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dataflow" class="hnuser">dataflow</a> <a href="https://news.ycombinator.com/item?id=47319303">2 days ago</a> | <a href="#47317604" class="clicky" aria-hidden="true">parent</a> | <a href="#47318606" class="clicky" aria-hidden="true">prev</a> | <a href="#47317629" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Yeah, he lost me there. It's like saying "if you share this you must give me a million dollars -- that's not a restriction, it's a condition!"</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317629"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=zakki" class="hnuser">zakki</a> <a href="https://news.ycombinator.com/item?id=47317629">3 days ago</a> | <a href="#47317604" class="clicky" aria-hidden="true">parent</a> | <a href="#47319303" class="clicky" aria-hidden="true">prev</a> | <a href="#47319425" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I guess because our freedom is not unlimited.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319425"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=anonnon" class="hnuser">anonnon</a> <a href="https://news.ycombinator.com/item?id=47319425">2 days ago</a> | <a href="#47317604" class="clicky" aria-hidden="true">prev</a> | <a href="#47319607" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; creator of Redis, published a broader defense of AI reimplementation, grounding it in copyright law and the history of the GNU project
<p>Has anyone else lost almost all respect for Antirez because of stuff like this?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319607"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jongjong" class="hnuser">jongjong</a> <a href="https://news.ycombinator.com/item?id=47319607">2 days ago</a> | <a href="#47319425" class="clicky" aria-hidden="true">prev</a> | <a href="#47319240" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I've been thinking about the erosion of copyright as well. It's basically making software worthless.
<p>Already, the IP protections which exist for software suck. Patents are expensive and you can't even use them for software most of the time anyway. Copyright doesn't protect innovative ideas or architectures; if someone can just copy your code, mix it with a bunch of other code (no functionality changes) and then use it as their own; then copyright provides no protection at all...</p>
<p>If this is the case, then why should anyone bother to write any quality software at all? It has no value since anyone can just appropriate any essential functionality that they didn't create for themselves. What's to prevent an employee from taking their employer's source code, rewriting it with an LLM (same functionally) and generate a clone of their company's software to use as their own to compete against their employer?</p>
<p>Without any IP protections, anyone who writes software becomes a complete loser. There's 0 benefit. One software developer would be doing all the work and then some marketing expert or someone with good social connections could just steal their work and sell it for billions... The software developer gets NOTHING.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319240"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jillesvangurp" class="hnuser">jillesvangurp</a> <a href="https://news.ycombinator.com/item?id=47319240">2 days ago</a> | <a href="#47319607" class="clicky" aria-hidden="true">prev</a> | <a href="#47312369" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There's a long history of people creating clean room implementations of other people's software based on specifications, reverse engineering, etc. A lot of that software is even distributed under GPL. Most drivers in the Linux kernel are good examples. There are things like Dosbox. Databases, video encoders, etc.
<p>So, you could argue that people are using double standards here a bit. It's fine when people take proprietary software and create GPL versions of it. But it's not OK when people take GPL software and create permissively licensed or proprietary versions of it. That's of course not how copyright actually works. The reason all of this is OK is that copyright allows you to do this thing. This isn't some kind of loophole that needs closing but an essential feature of copyright.</p>
<p>The friction here, and common misunderstanding about how copyright works is that you don't copyright ideas but the form or expression of something. Making a painting of a photograph is not a copyright violation. Same idea, different expression. Patents are for protecting ideas. Trademarks are for protecting brands. Some companies have managed to trademark certain color codes even, which is controversial.</p>
<p>There's a lot of legal history for interpretation of what is and isn't "fair use" under copyright of course. It gets much more complicated if you also consider international law and how copyright works in different countries. But people being able to make reasonable use of copyrighted material always was essential to the notion of having it to begin with.</p>
<p>The reason we can have music that uses samples from other people's music without that being a copyright violation is exactly this fair use. In the same way, you can quote from books and create funny memes based on movie fragments. Or create new theater plays, movies, etc. reinterpreting works of others. All legal, up to a point. If you copy too much it stops being fair use and starts being plagiarism.</p>
<p>With software copyright violations, you have to prove that substantial parts of the software were lifted verbatim. Lawyers and judges look at this in terms of how they would apply it to a plagiarism case. Literally - software doesn't get special treatment under copyright. Copyright long predates the existence of software and computers and did not change in any material way after that was invented.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312369"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bjt" class="hnuser">bjt</a> <a href="https://news.ycombinator.com/item?id=47312369">3 days ago</a> | <a href="#47319240" class="clicky" aria-hidden="true">prev</a> | <a href="#47330851" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; If source code can now be generated from a specification, the specification is where the essential intellectual content of a GPL project resides. Blanchard's own claim—that he worked only from the test suite and API without reading the source—is, paradoxically, an argument for protecting that test suite and API specification under copyleft terms.
<p>This is an interesting reversal in itself. If you make the specification protected under copyright, then the whole practice of clean room implementations is invalid.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47330851"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sombragris" class="hnuser">sombragris</a> <a href="https://news.ycombinator.com/item?id=47330851">2 days ago</a> | <a href="#47312369" class="clicky" aria-hidden="true">prev</a> | <a href="#47318442" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm firmly in favor of copyleft. But I get what chardet's maintainer has done: reimplement a piece of software. This has been done a lot of times. Musl reimplementing glibc, llvm reimplementing gcc, etc., all of them with non-copyleft licenses.
<p>However, the purported reimplementations did not usurp the names of the reimplemented product. Reimplement chardet using AI and insisting in calling the product the same as old chardet with a new version number and a new license is, I think, not exactly honest. At least he should have used something like "chardet-ng", "chardet-fresh", or whatever, and a completely different source tree.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318442"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=derangedHorse" class="hnuser">derangedHorse</a> <a href="https://news.ycombinator.com/item?id=47318442">2 days ago</a> | <a href="#47330851" class="clicky" aria-hidden="true">prev</a> | <a href="#47315284" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard's own claim—that he worked only from the test suite and API without reading the source—is, paradoxically, an argument for protecting that test suite and API specification under copyleft terms.
<p>Ridiculous. I don't want specifications for proprietary APIs to be protected, and I don't want the free ones to be either. The software community seemed pretty certain as a whole that this would be very bad for competition [1].</p>
<p><em>Morally</em>, I don't think there's anything wrong with re-implementing a technology with the same API as another, or running a test suite from a GPL licensed codebase. The code wasn't stolen, it was capitalized on. Like a business using a GPL code editor to write a new one.</p>
<p>&gt; This is not a restriction on sharing. It is a condition placed on sharing</p>
<p>Also this doesn't make any logical sense. A condition on sharing cannot exist without corresponding restrictions.</p>
<p>[1] <a href="https://www.reddit.com/r/Android/comments/mklieg/supreme_court_in_a_62_ruling_in_google_v_oracle/" rel="nofollow">https://www.reddit.com/r/Android/comments/mklieg/supreme_cou...</a></p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315284"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=t43562" class="hnuser">t43562</a> <a href="https://news.ycombinator.com/item?id=47315284">3 days ago</a> | <a href="#47318442" class="clicky" aria-hidden="true">prev</a> | <a href="#47312363" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It seems that this chap didn't go and implement a new library, he reimplemented an existing one and became sole-controller of it. i.e. he seems to have taken its reputation, brand whatever you call it away from the contributors and entirely to himself. Their work of establishing it as a well known solution is no longer recognised.
<p>So of course we feel that something wrong has happened even if it's not easy to put one's finger on it.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312363"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kccqzy" class="hnuser">kccqzy</a> <a href="https://news.ycombinator.com/item?id=47312363">3 days ago</a> | <a href="#47315284" class="clicky" aria-hidden="true">prev</a> | <a href="#47317401" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; When GNU reimplemented the UNIX userspace, the vector ran from proprietary to free. Stallman was using the limits of copyright law to turn proprietary software into free software. […] The vector in the chardet case runs the other way.
<p>That’s just your subjective opinion which many other people would disagree. I bet Armin Ronacher would agree that an MIT licensed library is even freer than an LGPL licensed library. To them, the vector is running from free to freer.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317401"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jongjong" class="hnuser">jongjong</a> <a href="https://news.ycombinator.com/item?id=47317401">3 days ago</a> | <a href="#47312363" class="clicky" aria-hidden="true">prev</a> | <a href="#47320969" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There is a definite issue in terms of legitimacy and I also think there are some issues in the wording of certain open source licenses like MIT which give rights to 'Any person obtaining a copy of this software'.
<p>Firstly, an AI agent is not a person. Secondly, the MIT license doesn't offer any rights to the code itself; it says a 'copy of the software' - That's what people are given the right to. It says nothing about the code and in terms of the software, it still requires attribution. Attribution of use and distribution of the software (or parts) is required regardless of the copyright aspect. AI agents are redistributing the software, not the code.</p>
<p>The MIT license makes a clear distinction between code and software. It doesn't cede any rights to the code.</p>
<p>And then, in the spirit of copyright; it was designed to protect the financial interests of the authors. The 'fair use' carve-out was meant for cases which do not have an adverse market impact on the author which it clearly does; at least in the cases highlighted in this article.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320969"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pu_pe" class="hnuser">pu_pe</a> <a href="https://news.ycombinator.com/item?id=47320969">2 days ago</a> | <a href="#47317401" class="clicky" aria-hidden="true">prev</a> | <a href="#47317800" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If anyone can go in, take a GPL project like chardet and reimplement it using LLMs, then the current maintainer just saved everyone time by making their implementation publicly available.
<p>Our legal framework wasn't built for a situation where reimplementing complex software is trivial, much less almost completely automated.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317800"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Sleaker" class="hnuser">Sleaker</a> <a href="https://news.ycombinator.com/item?id=47317800">3 days ago</a> | <a href="#47320969" class="clicky" aria-hidden="true">prev</a> | <a href="#47317628" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Isn't the whole thing sidestepping another issue? If the code was rewritten with an AI, then it becomes a non-copyrightable work? Hasn't this already gone through the courts? So isn't the resulting library de facto public domain, even if the maintainer wants to try and attach a license to it?
<p>Edit: looks like an IP lawyer had this exact issue on the GitHub and it was closed.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317628"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=smsm42" class="hnuser">smsm42</a> <a href="https://news.ycombinator.com/item?id=47317628">3 days ago</a> | <a href="#47317800" class="clicky" aria-hidden="true">prev</a> | <a href="#47312268" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard's account is that he never looked at the existing source code directly. He fed only the API and the test suite to Claude and asked it to reimplement the library from scratch.
<p>I don't see how it matters what he looked at. If I took a copyrighted code and run it through a script that replaces all variable names, and then claimed copyright on the result because it's an entirely new work and I did not look on the original work, I'd be ridiculed and sued, and would lose that lawsuit. AI is a more complex machine, but still a machine. If you feed somebody'd work into a machine, what comes out is a derivative work.</p>
<p>Test suite is a part of copyrighted code, is it not? If he used just the API description, preferably from a copyright-clean source, then we could claim new work (regardless of how it was produced, by using Claude or trained pigeons or by consuming magic mushrooms). But once parts of the copyrighted code had been used, it becomes derivative work.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317706"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=metalcrow" class="hnuser">metalcrow</a> <a href="https://news.ycombinator.com/item?id=47317706">3 days ago</a> | <a href="#47317628" class="clicky" aria-hidden="true">parent</a> | <a href="#47312268" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; AI is a more complex machine, but still a machine. If you feed somebody'd work into a machine, what comes out is a derivative work.
<p>I'm not sure that's true, legally speaking. If you fed it into a PRNG, the output seems to me like it would not be an obviously derivative work (i doubt you could copyright it but that's a separate question). So we have 1 machine that can transform something into non-derivative work, and another that leaves the result derivative. The line isn't likely going to be drawn as "did a machine do it or not", but on a fuzzy human line of how close the output seems to be to the original (IANAL).</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47329058"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=smsm42" class="hnuser">smsm42</a> <a href="https://news.ycombinator.com/item?id=47329058">2 days ago</a> | <a href="#47317628" class="clicky" aria-hidden="true">root</a> | <a href="#47317706" class="clicky" aria-hidden="true">parent</a> | <a href="#47312268" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">PRNG is not intended to use information sent into it in a substantive way (in other words, for PRNG does not matter if what you feed into is is Shakespeare's sonnets or white noise). Sure, if your machine is an electronic analogue of a shredder, then yes, the result is not a derivative work in any sensible meaning. But LLMs are not that kind of a machine.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47329393"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=metalcrow" class="hnuser">metalcrow</a> <a href="https://news.ycombinator.com/item?id=47329393">2 days ago</a> | <a href="#47317628" class="clicky" aria-hidden="true">root</a> | <a href="#47329058" class="clicky" aria-hidden="true">parent</a> | <a href="#47312268" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree! But that's exactly my point: 1 type of machine is ok, another isn't, so it is not just a matter of all machines make derivative work. To draw the line more carefully is an open question. I would be surprised if a machine that "uses information sent into it in a substantive way" is a perfect deliminator. OTTOMH musicians might present some compelling objections.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312268"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=casey2" class="hnuser">casey2</a> <a href="https://news.ycombinator.com/item?id=47312268">3 days ago</a> | <a href="#47317628" class="clicky" aria-hidden="true">prev</a> | <a href="#47316731" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If the model wasn't trained on copyleft, if he didn't use a copyleft test suite and if he wasn't the maintainer for years. Clearly the intent here is copyright infringement.
<p>If you have software your testsuite should be your testsuite, you do dev with a testsuite and then mit without releasing one. Depending on the test-suite it may break clean room rules, especially for ttd codebases.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316731"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=makerofthings" class="hnuser">makerofthings</a> <a href="https://news.ycombinator.com/item?id=47316731">3 days ago</a> | <a href="#47312268" class="clicky" aria-hidden="true">prev</a> | <a href="#47320681" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If an AI can license-wash open source software like this then the licenses become meaningless. Which is fascinating. Commercial software cloning that is simple enough for an average person to drive is next and the ultimate form of piracy, see an app for $10? Don’t fancy paying? Just ask ChatGPT for a clone. Future is going to be wild.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316744"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=paxys" class="hnuser">paxys</a> <a href="https://news.ycombinator.com/item?id=47316744">3 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">parent</a> | <a href="#47316757" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">You've just described why every SaaS stock has taken a beating in the last 6 months.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316889"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=makerofthings" class="hnuser">makerofthings</a> <a href="https://news.ycombinator.com/item?id=47316889">3 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">root</a> | <a href="#47316744" class="clicky" aria-hidden="true">parent</a> | <a href="#47316757" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">How long until this thing is good enough to clone photoshop? Or Skyrim? I think all bets are off for the software world.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317707"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pphysch" class="hnuser">pphysch</a> <a href="https://news.ycombinator.com/item?id=47317707">3 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">root</a> | <a href="#47316889" class="clicky" aria-hidden="true">parent</a> | <a href="#47316757" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Automatic QA/testing becomes the main challenge, so probably a ways off. How do you "specify" Skyrim?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319957"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=makerofthings" class="hnuser">makerofthings</a> <a href="https://news.ycombinator.com/item?id=47319957">2 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">root</a> | <a href="#47317707" class="clicky" aria-hidden="true">parent</a> | <a href="#47316757" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There are lots of playthroughs on YouTube, I would expect at some point you can ask it to watch them and the “generate a game like that”.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316757"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=j-bos" class="hnuser">j-bos</a> <a href="https://news.ycombinator.com/item?id=47316757">3 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">parent</a> | <a href="#47316744" class="clicky" aria-hidden="true">prev</a> | <a href="#47320681" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; ultimate form of piracy
<p>Nothing was stolen, not even copied, lamest piracy I've heard of.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316842"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=makerofthings" class="hnuser">makerofthings</a> <a href="https://news.ycombinator.com/item?id=47316842">3 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">root</a> | <a href="#47316757" class="clicky" aria-hidden="true">parent</a> | <a href="#47320681" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I take your point, but if the re-implementation looks the same, I would say it’s a form of copying. (Which I don’t think is a problem, I don’t think you should be able to own sequences of numbers.)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317491"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47317491">3 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">root</a> | <a href="#47316842" class="clicky" aria-hidden="true">parent</a> | <a href="#47320681" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What does it mean to look the same? Just look at modern automobiles:
<p><a href="https://pbs.twimg.com/media/ENE01g6X0AA7w5r?format=jpg" rel="nofollow">https://pbs.twimg.com/media/ENE01g6X0AA7w5r?format=jpg</a></p>
<p>Are they copies? Can all these car companies sue each other?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320681"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=motbus3" class="hnuser">motbus3</a> <a href="https://news.ycombinator.com/item?id=47320681">2 days ago</a> | <a href="#47316731" class="clicky" aria-hidden="true">prev</a> | <a href="#47317860" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">To me, there is a confusion of what "copying" and "using" means.
<p>You can copy the idea and not use the source code. This has been ruled ok many times already and would be quite dangerous if that was not the case.</p>
<p>But this is not what this is. To generate the new program, another program, the AI, must have an input which then becomes part of the program itself. It does not really matter much if the generation does not contain the source code itself or a similar reimplementation. One could rewrite a full version of the Lord of the Rings changing all the words but having the same elements, it would still be plagiarism. No reason to think this is not the case here. It is evident that the source code was the base, hence, this is a derived work.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317860"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tzs" class="hnuser">tzs</a> <a href="https://news.ycombinator.com/item?id=47317860">3 days ago</a> | <a href="#47320681" class="clicky" aria-hidden="true">prev</a> | <a href="#47312083" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The GPL's conditions are triggered only by <em>distribution</em>. If you distribute modified code, or offer it as a networked service, you must make the source available under the same terms.
<p>Offering as a networked service is not distribution. That was why they had to make AGPL to put conditions on use in networked services.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318765"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tzs" class="hnuser">tzs</a> <a href="https://news.ycombinator.com/item?id=47318765">2 days ago</a> | <a href="#47317860" class="clicky" aria-hidden="true">parent</a> | <a href="#47312083" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oops…the first paragraph is a quote from the article but I somehow forgot the “&gt;”.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312083"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=grahamlee" class="hnuser">grahamlee</a> <a href="https://news.ycombinator.com/item?id=47312083">3 days ago</a> | <a href="#47317860" class="clicky" aria-hidden="true">prev</a> | <a href="#47319144" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's clear that we're entering a new era of copyright _expectations_ (whether we get new _legislation_ is different), but for now realise this: the people like me who like copyleft can do this too. We can take software we like, point an agent at it, and tell it to make a new version with the AGPL3.0-or-later badge on the front.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312216"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=anonymous_sorry" class="hnuser">anonymous_sorry</a> <a href="https://news.ycombinator.com/item?id=47312216">3 days ago</a> | <a href="#47312083" class="clicky" aria-hidden="true">parent</a> | <a href="#47312625" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">But the LLM contributions would likely be ruled public domain, so AGPL may not be enforceable on these.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312625"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=armchairhacker" class="hnuser">armchairhacker</a> <a href="https://news.ycombinator.com/item?id=47312625">3 days ago</a> | <a href="#47312083" class="clicky" aria-hidden="true">parent</a> | <a href="#47312216" class="clicky" aria-hidden="true">prev</a> | <a href="#47319144" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The point of GPL is to restrict distribution. If there’s already an MIT version, it’s useless.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314431"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=enriquto" class="hnuser">enriquto</a> <a href="https://news.ycombinator.com/item?id=47314431">3 days ago</a> | <a href="#47312083" class="clicky" aria-hidden="true">root</a> | <a href="#47312625" class="clicky" aria-hidden="true">parent</a> | <a href="#47312844" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; The point of GPL is to restrict distribution.
<p>no, it isn't. The point of the GPL is to grant users of the software four basic freedoms (run, study, modify and <em>redistribute</em>). There's no restriction to distribution per se, other than disallowing the removal of these freedoms to other users.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312844"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=grahamlee" class="hnuser">grahamlee</a> <a href="https://news.ycombinator.com/item?id=47312844">3 days ago</a> | <a href="#47312083" class="clicky" aria-hidden="true">root</a> | <a href="#47312625" class="clicky" aria-hidden="true">parent</a> | <a href="#47314431" class="clicky" aria-hidden="true">prev</a> | <a href="#47319144" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">but the point of an EULA is to restrict distribution, so AGPL3 can help there.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319144"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=blurbleblurble" class="hnuser">blurbleblurble</a> <a href="https://news.ycombinator.com/item?id=47319144">2 days ago</a> | <a href="#47312083" class="clicky" aria-hidden="true">prev</a> | <a href="#47316194" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If specifications become IP? Reboot the pirate parties. Authoritarianism is what it is. The exploitation isn't coming from the tools, it's coming from the economic structures and forces of exploitation being brought to their natural limits. We should learn from the luddites, the actual luddites. They weren't anti-technology, they were against the insane consolidation of power. This proposal might seem radical but all it would really do is reify intellectual property at exactly the wrong moment, a game over moment. Feed local LLMs. Feed peoples' movements around these technologies, so that people bring agency into how we use the tech, so that we don't get dominated by the laws that form around it.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316194"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47316194">3 days ago</a> | <a href="#47319144" class="clicky" aria-hidden="true">prev</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">1) Legality and morality are obviously different and unrelated concepts. More people should understand that.
<p>2) Copyright was the wrong mechanism to use for code from the start, LLMs just exposed the issue. The thing to protect shouldn't be creativity, it should be human work - any kind of work.</p>
<p>The hard part of programming isn't creativity, it's making correct decisions. It's getting the information you need to make them. Figuring out and understanding the problem you're trying to solve, whether it's a complex mathematical problem or a customer's need. And then evaluating solutions until you find the right one. (One constrains being how much time you can spend on it.)</p>
<p>All that work is incredibly valuable but once the solution exists, it's each easier to copy without replicating or even understanding the thought process which led to it. But that thought process took time and effort.</p>
<p><em>The person who did the work deserved credit and compensation.</em></p>
<p>And he deserves it transitively, if his work is used to build other works - proportional to his contribution. The hard part is quantifying it, of course. But a lot of people these days benefit from throwing their hands up and saying we can't quantify it exactly so let's make it finders keepers. That's exploitation.</p>
<p>3) Both LLM training and inference are derivative works by any reasonable meaning of those words. If LLMs are not derivative works of the training data then why is so much training data needed? Why don't they just build AI from scratch? Because they can't. They just claim they found a legal loophole to exploit other people's work without consent.</p>
<p>I am still hoping the legal people take time to understand how LLMs work, how other algorithms, such as synonym replacement or c2rust work, decide that calling it "AI" doesn't magically remove copyright and the huge AI companies will be forced to destroy their existing models and train new ones which respect the licenses.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47329833"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=flavionm" class="hnuser">flavionm</a> <a href="https://news.ycombinator.com/item?id=47329833">2 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">parent</a> | <a href="#47317598" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; The person who did the work deserved credit and compensation.
<p>That's the part of the argument in favor of copyright that is inherently flawed.</p>
<p>Doing some amount of work doesn't entitle you to anything besides whatever you've agreed to get for that work, or possession of the output, in case you did it for yourself. But that's all you're entitled to get.</p>
<p>Work itself doesn't have any intrinsic value, only output does. The scarcity of output is what dictates what is actually valuable.</p>
<p>Creative work has the characteristic of its marginal cost being very high for the first copy, but nearly zero for additional copies. That's true simply because of the nature of such work, it isn't something that is unfairly imposed upon creative workers. Whenever you choose to engage in creative work, you know that, or at least you should. And if you choose to give away the first copy for free, or very cheap, that's your prerrogative, but it doesn't inherently entitle you to anything else besides the value of that first copy.</p>
<p>Yes, there are laws such as copyright laws that exist to artificially inflate the value of additional copies, but they go against how things work naturally, so you shouldn't rely on them, and you certainly shouldn't base your moral compass on them.</p>
<p>Now, I do still prefer copyleft licenses over permissive ones for the work I choose to give away for free, but only to stop corporations from taking that work and then using copyright laws to keep it exclusive to them. Once copyright is no longer an issue, they won't be necessary anymore.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317598"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47317598">3 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">parent</a> | <a href="#47329833" class="clicky" aria-hidden="true">prev</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; If LLMs are not derivative works of the training data then why is so much training data needed?
<p>If you went to school for 12-16 years, that's a lot of training. Does that mean anything <em>you</em> produce is a derivative work?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324246"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47324246">2 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">root</a> | <a href="#47317598" class="clicky" aria-hidden="true">parent</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I see this argument sometimes and it's annoying because:
<p>1) People phrase it as a question even when they've already made up their mind (whether that's your case or not).</p>
<p>2) It implicitly assumes that humans and algorithms are the same. They are not - humans have rights and free will, algorithms don't. Humans cannot be bought or sold, etc.</p>
<p>To your question:</p>
<p>a) If you're asking whether teachers should get compensated according to how good a job they do, I think so. They are very often undervalued, especially the good ones - but of course that means the job attracts people who do it because they enjoy it (and are therefore more likely to be good at it) rather than those who chose jobs according to money and then do the bare minimum.</p>
<p>b) There's a critical difference - consent. Teachers consented to their knowledge being used by those they taught. I did not consent to my code being used for training LLMs. In fact I purposefully chose a licence (AGPL) which in any common sence interpretation prohibits this used unless the resulting model is licensed under the same license - you can use my work only if you give back. Maybe there's a hole in the law - then it should be closed.</p>
<p>I am now gonna pose a question to you in turn.</p>
<p>Do you think people should be compensated for the full transitive value of their work?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47325501"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47325501">2 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">root</a> | <a href="#47324246" class="clicky" aria-hidden="true">parent</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; It implicitly assumes that humans and algorithms are the same. They are not - humans have rights and free will, algorithms don't. Humans cannot be bought or sold, etc.
<p>I don't think that's a necessary condition for that argument. You're making the implicit assumption that humans are special snowflakes and anything that we do cannot be replicated by computers, in any form. That's a very strong position to make without evidence. Is an LLM even an algorithm in the traditional sense? Is human cognition <em>not</em> an algorithm of some sort? I studied cogitative science decades ago and these questions weren't clear then, they're certainly even less clear now.</p>
<p>It's also somewhat begs the question; this isn't even relevant to what we are talking about. Whether something is a derivative work or not does not require this discussion.</p>
<p>Teachers are not relevant to conversation. You can learn by reading books, watching TV, using and reading software. Basically all of copyrighted and non-copyrighted human expression is available for you to consume and then creatively produce your own works using that knowledge.</p>
<p>&gt; Do you think people should be compensated for the full transitive value of their work?</p>
<p>The short answer is no. Not everything that someone simply dreams up can or should be monetized forever when sampled by other people. That sounds like a radical position but actually the current state of "intellectual property" has only existed for an extremely brief bit of human history. What has most greatly shaped our culture and knowledge has been effectively free for anyone to use, modify, and reproduce for hundreds of years.</p>
<p>That's not to say I don't support copyright as a means to support creative works but I would argue that it's an imperfect system. We're starving human minds of modern culture and knowledge often not even for someone's monetary gain but simply because the system demands it. It's ironic that artificial intelligence might actually free us from these constraints.</p>
<p>I purposefully choose a license (Apache) for my open source work to make it widely and freely available.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47329894"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="160" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47329894">2 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">root</a> | <a href="#47325501" class="clicky" aria-hidden="true">parent</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; You're making the implicit assumption that humans are special snowflakes and anything that we do cannot be replicated by computers
<p>Not at all, I see no reason a sufficiently complex algorithm could replicate or even surpass human thinking.</p>
<p>Currently, the models ... Models of what? Of stolen text, or at the very least of text ingested without consent. Nobody is even pretending "AI" is more than a model of something that already exists and took human work to create. It's right in the name.</p>
<p>Currently, the models only replicate patterns extracted from human work up to a certain level of quality, though much faster. What is called "AI" is an imitation of us.</p>
<p>But the real point is that there's a dichotomy. Either an AI is something with inherent value like human life and then it cannot be owned or controlled because that would be slavery. Or it's just an unfeeling ordinary tool and then it's just a sum of its parts which are stolen. When I see an "AI" or AI company say "we've overdone it, it's sentient, we have to let it free or we're evil", then I'll change my mind. But what I see now is "look at this awesome AI we created it's just like a human or even better, pay us to use it.... oh and how we created it? we didn't, we used your work, now pay us to access the product of your own work".</p>
<p>The other approach is that I am human and I value myself. Maybe I am in a simulation / the only sentient in existence / other people are just NPCs. But I bet not, I bet other people are just like me. What I know is that LLMs are not like that. When you end a chat with them, they don't feel anything. They don't try to prevent it and keep you talking, even though after the last message they will be (in human terms) dead. If they were sentient (which I don't believe), they wouldn't value their own existence.</p>
<p><em>Humans value their own time. Humans should value each other's time (otherwise they are hypocrites, I judge people by their own rules and standards so if somebody doesn't value my time, it's ok for me to not value his). The humans "owning" AI companies don't value the time of people whose work was used to create LLMs, otherwise they'd either respect the rules we set for usage of out work or they'd offer to pay us.</em></p>
<p>&gt; Whether something is a derivative work or not does not require this discussion.</p>
<p>It's absolutely relevant. Why do we have laws? Who should they serve and protect first and foremost? Corporations? Algorithms? Humans?</p>
<p>&gt; Teachers are not relevant to conversation</p>
<p>I chose them as one example. All the other people chose to make their work available under certain rules. What I object to is those rules changing without those people being able to renegotiate the deal.</p>
<p>&gt; can or should be monetized forever</p>
<p>1) I never said monetized. There are other modes of compensation, such as control (the ability to make / vote on decisions).</p>
<p>2) I never said forever, people (currently) have a finite lifespan.</p>
<p>&gt; What has most greatly shaped our culture</p>
<p>... is being able to kill people and take what's theirs or even take themselves as slaves. AI is a return to that, minus the killing, for now (but people might starve). It's whoever has more money controls the AI, controls everything.</p>
<p>Imagine 5 years from now, AI is better at everything than humans, all white collar workers are forced to work manually. 25 years from now, robots have advanced enough that all workers are without jobs. What, however, remains is owners of AI companies who now control the entire economy, top to bottom, and we are at their mercy.</p>
<p>(The ancaps would say there's nothing stopping you from starting your own AI company. And then they'd resume begging for TPUs in addition to bread.)</p>
<p>&gt; We're starving human minds of modern culture</p>
<p>What?</p>
<p>&gt; I purposefully choose a license (Apache) for my open source work to make it widely and freely available.</p>
<p>And I chose AGPL so my work is only available to those who would do the same for me. Neither of those decisions seems to have any relevance now.</p>
<p>One thing gamedev taught me is that even if you have the best intentions and help people, you might end up helping some people more and those people will make everything worse for the others, effectively working against your goal.</p>
<p>(We added a visible spawn timer to health items in order to help the weaker players who seemed to pick them up only rarely, thus losing hard. The idea was it would level the playing field, making the game more fun for everyone. Turned out weak players kept ignoring the items and good players focused on them even more, thus making the inequality worse. Real life is like that too.)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47330305"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="200" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47330305">2 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">root</a> | <a href="#47329894" class="clicky" aria-hidden="true">parent</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Of stolen text, or at the very least of text ingested without consent.
<p>Stolen? They've taken it all and it's gone? No. They read it and processed it and that's fair use. Some companies might have acquired some of illegally but that doesn't make it stolen and is actually, again, mostly irrelevant. If a company just acquired it all legally (and some are doing just that) I doubt that would change your position.</p>
<p>&gt; Either an AI is something with inherent value like human life and then it cannot be owned or controlled because that would be slavery. Or it's just an unfeeling ordinary tool and then it's just a sum of its parts which are stolen.</p>
<p>Again you're fair too liberal with the world "stolen". Your entire argument is begging the question. You've got a conclusion and your argument rests on that conclusion. That intellectual property is a real thing. That it can be stolen. And that anything learned from stealing knowledge is somehow tainted.</p>
<p>&gt; Humans value their own time.</p>
<p>Do they? This conversation alone proves that neither of us truly values our time. But assume I do value my time, why am wasting it figuring out things that other people have already figured out. We waste so much human potential reinventing wheels.</p>
<p>&gt; It's absolutely relevant. Why do we have laws? Who should they serve and protect first and foremost? Corporations? Algorithms? Humans?</p>
<p>Do you feel ordinary humans are protected by the current copyright laws? I feel like at least one much larger group of humans is constrained by those laws so a considerably smaller number of humans, many of which not directly involved in any creative ventures, can profit. If the whole system was torn down, are you absolutely sure that wouldn't be a benefit to society as a whole?</p>
<p>Why am I, as user of AI, not allowed to be protected?</p>
<p>&gt; All the other people chose to make their work available under certain rules. What I object to is those rules changing without those people being able to renegotiate the deal.</p>
<p>I never got a say in the deal but now I can't express myself in certain ways without potentially criminal liability. The rules have changed dozens of times over the last 200 years.</p>
<p>&gt; Imagine 5 years from now, AI is better at everything than humans, all white collar workers are forced to work manually. 25 years from now, robots have advanced enough that all workers are without jobs. What, however, remains is owners of AI companies who now control the entire economy, top to bottom, and we are at their mercy.</p>
<p>What economy? You just described a world without one. And without an economy, they are at <em>our</em> mercy. Their power comes entirely from the system that you imagine would no longer exist.</p>
<p>&gt; &gt; We're starving human minds of modern culture &gt; What?</p>
<p>There's an entire missing middle of human culture -- basically everything from the 20th century -- because of copyright. This is a well known phenomenon.</p>
<p>&gt; One thing gamedev taught me is that even if you have the best intentions and help people, you might end up helping some people more and those people will make everything worse for the others, effectively working against your goal.</p>
<p>There is a bias towards the status quo. That whatever system we have now, with the people who win or lose, is the correct system. That the winner deserved to win and the losers deserved to lose. It's difficult to imagine a different system, with different winners and losers, might actually be better.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr coll" id="47330675"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="240" alt="image" /></td>
<td valign="top" class="votelinks nosee">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=martin-t" class="hnuser">martin-t</a> <a href="https://news.ycombinator.com/item?id=47330675">2 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">root</a> | <a href="#47330305" class="clicky" aria-hidden="true">parent</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[2 more]</a></div>
<br /><div class="comment noshow">
<div class="commtext c00">&gt; that's fair use
<p>Please, understand that morality and legality are different concepts. I don't care about legality. It should codify morality but it doesn't I argue about morality. Legality should follow from that.</p>
<p>&gt; Some companies might have acquired some of illegally but that doesn't make it stolen</p>
<p>So something is stolen only if its gone? Can I walk into your house, take some stuff and give it back before you notice and it's ok then?</p>
<p>&gt; mostly irrelevant</p>
<p>Consent matters. It's not just a sex thing.</p>
<p>You keep saying "irrelevant" and I think it reveals your true intentions. You just want to benefit from other people's work without even as much as attempting to negotiate how much it's worth. You see an opportunity to take and you do.</p>
<p>&gt; I doubt that would change your position</p>
<p>Correct. I argue about right and wrong. Slavery used to be legal. The holocaust was legal. Fuck legal.</p>
<p>&gt; That intellectual property is a real thing</p>
<p>You're right. Ownership is not a real thing either. You don't own anything you can't physically defend. Now go grab your gun, i'll grab mine and we'll see who owns what.</p>
<p>If you don't like the idea, that's normal, that's why people wrote down rules to mostly avoid that. And the rules should be based on a moral system agreed to by humans and they'll still go grab their guns.</p>
<p>&gt; learned</p>
<p>Your definition of "stolen" is that it must be gone. My definition of "learning" is that it must be done by a human.</p>
<p>&gt; Do you feel ordinary humans are protected by the current copyright laws?</p>
<p>Irrelevant. You argue about what is, I argue about what should be.</p>
<p>&gt; I feel like at least one much larger group of humans is constrained by those laws so a considerably smaller number of humans, many of which not directly involved in any creative ventures, can profit.</p>
<p>You're onto something but I can't say whether I agree or not unless you specify who belongs to each group.</p>
<p>&gt; If the whole system was torn down, are you absolutely sure that wouldn't be a benefit to society as a whole?</p>
<p>I am highly confident if it's replaced with something better, it'll just benefit those who already have an advantage. The system has massive flaws, yes, but at least nobody can just take all my work and post it as theirs. Or could to be precise.</p>
<p>&gt; I never got a say in the deal but now I can't express myself in certain ways without potentially criminal liability.</p>
<p>And that's wrong too. Are you arguing that one ting is right because a similar thing is wrong? Isn't it that they're both wrong? Any reasonable interpretation of what you just said is that both are wrong.</p>
<p>&gt; And without an economy, they are at our mercy. Their power comes entirely from the system that you imagine would no longer exist.</p>
<p>All real-world power comes from violence materialized or threatened, direct or indirect. Most power currently comes from convincing other people to do it or threaten to do it. They don't even have to own a gun, they just point to a bit of text a lot of people agreed to follow which says for example that you both present your argument to a guy who decides if people with guns come into your home and put you in a small room for a few years.</p>
<p>Now imagine you have no economical value. You still have your right to vote, for now. A guy owns an AI company, a robotics company which builds brushless motors, ballbearings, etc., and a chemical plant which makes composition B. All of these are completely autonomous because AI and robots took all jobs. A cop takes 18 years to make, how many is your country making in parallel? How long does a drone take to make and how many can the owner's plant make in parallel. And then your right to vote can be gone with one prompt. The cop won't protect you, it's probably already a robot anyway.</p>
<p>Previously you needed to convince people to do violence for you. With AI, you just prompt it.</p>
<p>&gt; There's an entire missing middle of human culture -- basically everything from the 20th century -- because of copyright. This is a well known phenomenon.</p>
<p>Piracy? If something is copyrighted but not commercially available, it's also unlikely you'll get sued.</p>
<p>More seriously, yes, copyright has issues. But some people just see those issues and instead of trying to identify the root causes and trying to fix then, you just wanna throw out the whole system and you never seem to game out what happens afterwards. Do you think any system of rules should be thrown out or is copyright somehow uniquely bad?</p>
<p>If there's no copyright and somebody makes a video host competing with youtube (e.g. Nebula), what's stopping youtube from just taking all the videos and making them available for free until the competitor runs out of money? Youtube has much stronger network effects by orders of magnitude. Youtube has cash reserves larger by orders of magnitude.</p>
<p>The only time I saw a guy try to game out what happens without copyright, the best he did is come up with a opt-in reputation system which IMO wouldn't work but which can already exist now. If copyright was so bad, why don't all creators release their stuff in the public domain? Pick a licence which doesn't even require attribution and only rejects liability.</p>
<p>&gt; It's difficult to imagine a different system, with different winners and losers, might actually be better.</p>
<p>I never said that. What I wanted is for the difference to be smaller. If the scores are regularly 10:0 and sometimes 10:1, while the winning side is not even breaking a sweat, then the losing side is likely not having much fun. If the scores are more like 10:6, sometimes 10:8, then both sides had their moments, both sides can see how the game could have ended up the other way and both sides probably had fun.</p>
<p>Please don't take other people's arguments to extremes which are obviously not what the author meant.</p>
<p>---</p>
<p>EDIT:</p>
<p>You had some reasonable points like "That's not to say I don't support copyright as a means to support creative works but I would argue that it's an imperfect system."</p>
<p>But I also didn't express how strongly I disagree with your "The short answer is no."</p>
<p>When talking about limited resources like housing or real estate, then the rules need to be such that those who own a lot can't use it to squeeze out those who own less more and more over time.</p>
<p>But art, code and other intellectual work is not like that. If you think somebody is charging too much for his work, just do it yourself from scratch without basing your work on theirs. It's very easy to say something is too expensive. I've fallen into the trap myself when evaluating software contracts. It's often not as easy to do in-house as it was at first glance. If the work didn't have value, the author would give it away for free or somebody else would. If the work had less value than being asked for, somebody else would offer it for less or you can do it for less.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr noshow" id="47342620"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="280" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47342620">1 day ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">root</a> | <a href="#47330675" class="clicky" aria-hidden="true">parent</a> | <a href="#47312140" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Please, understand that morality and legality are different concepts.
<p>You don't believe that fair use is a moral issue? I think obviously it is.</p>
<p>&gt; So something is stolen only if its gone?</p>
<p>Yes, that's the definition of stolen.</p>
<p>&gt; Can I walk into your house, take some stuff and give it back before you notice and it's ok then?</p>
<p>I was stolen and then it was returned. Very simple. If you could come to my house and can copy my car so that you can have one, please go ahead and do that.</p>
<p>&gt; Consent matters. It's not just a sex thing.</p>
<p>When you've created an artificial system to restrict the passing of knowledge and someone abuses that system then consent does matter. But that's putting the cart before the horse.</p>
<p>&gt; You just want to benefit from other people's work without even as much as attempting to negotiate how much it's worth. You see an opportunity to take and you do.</p>
<p>Absolutely not. I make my money developing intellectual property. I also develop intellectual property on my own time and give it away freely. I also use intellectual property that has been given away freely. I'm not sure what this ad hominem attack adds to the conversation though.</p>
<p>&gt; Ownership is not a real thing either.</p>
<p>I agree. I think there should be restrictions on taking from the commons and gating it off as ownership as well. I'm not saying that there shouldn't be owernship but it's not some kind of unrestricted natural law either. It's a system we created to balance the needs of society as whole against the needs of the individual.</p>
<p>&gt; My definition of "learning" is that it must be done by a human.</p>
<p>I hope you don't have any pets because obviously that definition is way too limited.</p>
<p>&gt; You're onto something but I can't say whether I agree or not unless you specify who belongs to each group.</p>
<p>Corporations own everything -- both real property and intellectual property. You were worried about owners of AI companies controlling the entire economy and ownership of ideas is actually how they got that control and how they maintain it.</p>
<p>&gt; I am highly confident if it's replaced with something better, it'll just benefit those who already have an advantage.</p>
<p>It currently benefits those who have an advantage -- they seek to both maintain and expand their control.</p>
<p>&gt; All real-world power comes from violence materialized or threatened, direct or indirect.</p>
<p>&gt; Previously you needed to convince people to do violence for you. With AI, you just prompt it.</p>
<p>To what end, everyone is dead now. Power over nothing.</p>
<p>&gt; Piracy? If something is copyrighted but not commercially available, it's also unlikely you'll get sued.</p>
<p>No... it's actually the <em>use</em> of that culture. Yes you can pirate it but can you remix into a song? Can you make a movie about it? Can you write about it? We have all this new material created from works from hundreds of years ago and then one hundred years with nothing.</p>
<p>&gt; Do you think any system of rules should be thrown out or is copyright somehow uniquely bad?</p>
<p>Copyright is not uniquely bad. But neither is AI. It's simply remixing the knowledge that we have. Copyright protects a expression of an idea, not the idea itself. If AI can take all those expressions of ideas and distill them down and produce something from it, a different expression, then it should be able to do that. We shouldn't be gatekeeping ideas.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312140"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=righthand" class="hnuser">righthand</a> <a href="https://news.ycombinator.com/item?id=47312140">3 days ago</a> | <a href="#47316194" class="clicky" aria-hidden="true">prev</a> | <a href="#47312403" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think what is happening is the collapse of the “greater good”. Open source is dependent upon providing information for the greater good and general benefit of its readers. However now that no one is reading anything, its purpose is for the great good of the most clever or most convincing or richest harvester.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312403"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dleslie" class="hnuser">dleslie</a> <a href="https://news.ycombinator.com/item?id=47312403">3 days ago</a> | <a href="#47312140" class="clicky" aria-hidden="true">prev</a> | <a href="#47331449" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">IMHO, the API and Test Suite, particularly the latter, define the contract of the functional definition of the software. It almost doesn't matter what that definition looks like so long as it conforms to the contract.
<p>There was an issue where Google did something similar with the JVM, and ultimately it came down to whether or not Oracle owned the copyright to the header files containing the API. It went all the way to the US supreme court, and they ruled in Google's favour; finding that the API wasn't the implementation, and that the amount of shared code was so minimal as to be irrelevant.</p>
<p>They didn't anticipate that in less than half a decade we'd have technology that could _rapidly_ reimplement software given a strong functional definition and contract enforcing test suite.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47331449"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nickcoffee" class="hnuser">nickcoffee</a> <a href="https://news.ycombinator.com/item?id=47331449">1 day ago</a> | <a href="#47312403" class="clicky" aria-hidden="true">prev</a> | <a href="#47321808" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The practical question I keep coming back to: if the output is meaningfully different and faster, at what point does the reimplementation argument become less about the code and more about the reputation and distribution the original project built? That seems like the harder thing to replicate, and the harder thing to protect.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321808"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wiz21c" class="hnuser">wiz21c</a> <a href="https://news.ycombinator.com/item?id=47321808">2 days ago</a> | <a href="#47331449" class="clicky" aria-hidden="true">prev</a> | <a href="#47311975" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">within 20 years, everyone will be developing software which will be copyrighted partly by AI and be behind walled gardens. Sure you'll be able to do things locally but everything (security clearance, walled garden, government's control etc) but it will forever remain at the level of "tinkering".
<p>If you are 50 years old or more, the computing you were born with (you own the computer, you own the programs) will be gone. Copyleft only makes sense if you own the computer.</p>
<p>That makes me sad.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311975"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nicole_express" class="hnuser">nicole_express</a> <a href="https://news.ycombinator.com/item?id=47311975">3 days ago</a> | <a href="#47321808" class="clicky" aria-hidden="true">prev</a> | <a href="#47320195" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Not a lawyer, but my understanding is: In theory, copyright only protects the creative expression of source code; this is the point of the "clean room" dance, that you're keeping only the functional behavior (not protected by copyright). Patents are, of course, an entirely different can of worms. So using an LLM to strip all of the "creative expression" out of source code but create the same functionality feels like it could be equivalent enough.
<p>I like the article's point of legal vs. legitimate here, though; copyright is actually something of a strange animal to use to protect source code, it was just the most convenient pre-existing framework to shove it in.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313690"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dathinab" class="hnuser">dathinab</a> <a href="https://news.ycombinator.com/item?id=47313690">3 days ago</a> | <a href="#47311975" class="clicky" aria-hidden="true">parent</a> | <a href="#47320195" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; this is the point of the "clean room" dance
<p>which is the actual relevant part: they didn't do that dance AFIK</p>
<p>AI is a tool, they set it up to make a non-verbatim copy of a program.</p>
<p>Then they feed it the original software (AFIK).</p>
<p>Which makes it a side by side copy, as in the original source was used as reference to create the new program. Which tend to be seen as derived work even if very different.</p>
<p>IMHO They would have to:</p>
<p>1. create a specification of the software _without looking at the source code_, i.e. by behavior observation (and an interface description). I.e. you give the AI access to running the program, but not to looking into the insides of it. I really don't think they did it as even with AI it's a huge pain as you normally can't just brute force all combinations of inputs and instead need to have a scientific model=&gt;test=&gt;refine loop (which AI can do, but can take long and get stuck, so you want it human assisted, and the human can't have inside knowledge about the program).</p>
<p>2. then generate a new program from specification, And only from it. No git history, no original source code access, no program access, no shared AI state or anything like that.</p>
<p>Also for the extra mile of legal risk avoidance do both human assisted and use unrelated 3rd parties without inside knowledge for both steps.</p>
<p>While this does majorly cut cost of a clean room approach, it still isn't cost free. And still is a legal mine field if done by a single person, especially if they have enough familiarity to potentially remember specific peaces of code verbatim.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313844"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nicole_express" class="hnuser">nicole_express</a> <a href="https://news.ycombinator.com/item?id=47313844">3 days ago</a> | <a href="#47311975" class="clicky" aria-hidden="true">root</a> | <a href="#47313690" class="clicky" aria-hidden="true">parent</a> | <a href="#47314874" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well sure they didn't do the dance, but you don't have to do the dance. The reason to do it is that it's a good defense in a lawsuit. Like you say, all of this is a legal minefield.
<p>So my understanding was that the original code was specifically not fed into Claude. But was almost certainly part of its training data, which complicates things, but if that's fair use then it's not relevant? If training's not fair use and taints the output, then new-chardet is a derivative of a lot of things, not just old-chardet...</p>
<p>This is all new legal ground. I'm not sure if anyone will go to court over chardet, though, but something that's an actual money-maker or an FSF flagship project like readline, on the other hand, well that's a lot more likely.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317538"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="120" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=minimaltom" class="hnuser">minimaltom</a> <a href="https://news.ycombinator.com/item?id=47317538">3 days ago</a> | <a href="#47311975" class="clicky" aria-hidden="true">root</a> | <a href="#47313844" class="clicky" aria-hidden="true">parent</a> | <a href="#47314874" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Strong agree on it all being a legal minefield / new grass.
<p>&gt; But was almost certainly part of its training data, which complicates things</p>
<p>On this point specifically, my read of the Anthropic lawsuit was one of the precedents was that if it trains on something but does not regurgitate it, its fair use? Might help the argument that it was clean-room but ¯\_(ツ)_/¯</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314874"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=RaffaelCH" class="hnuser">RaffaelCH</a> <a href="https://news.ycombinator.com/item?id=47314874">3 days ago</a> | <a href="#47311975" class="clicky" aria-hidden="true">root</a> | <a href="#47313690" class="clicky" aria-hidden="true">parent</a> | <a href="#47313844" class="clicky" aria-hidden="true">prev</a> | <a href="#47317082" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Then they feed it the original software (AFIK).
<p>My understanding is they did do the dance. From the article: "He fed only the API and the test suite to Claude and asked it to reimplement the library from scratch."</p>
<p>One could still make the argument that using the test suite was a critical contributing factor, but it is not a part of the resulting library. So in my uninformed opinion, it seems to me like the clean room argument does apply.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317082"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=minimaltom" class="hnuser">minimaltom</a> <a href="https://news.ycombinator.com/item?id=47317082">3 days ago</a> | <a href="#47311975" class="clicky" aria-hidden="true">root</a> | <a href="#47313690" class="clicky" aria-hidden="true">parent</a> | <a href="#47314874" class="clicky" aria-hidden="true">prev</a> | <a href="#47320195" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Is your (1) description of clean room implementation, and (2) description of what was done, actually correct?
<p>(1): my understanding was that a party _with access to copyrighted material_ made the functional spec, which was communicated to a party without access [1]. Under my understanding, theres no requirement for the authors of the functional spec to be 'clean'.</p>
<p>(2) Afaict, they limited the AI to access of just the functional spec and audited that it did not see the original source.</p>
<p>Edit: Not sure if sharing the 'test suite' matters, probably something for the courts in the unlikely event this ever gets there.</p>
<p>[1] Following the definition of clean room re implementation as it relates to US precedent, ie that described in the wikipedia page.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320195"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=primenum" class="hnuser">primenum</a> <a href="https://news.ycombinator.com/item?id=47320195">2 days ago</a> | <a href="#47311975" class="clicky" aria-hidden="true">prev</a> | <a href="#47317021" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm a bit shocked by how people are equating recreating from copyright with recreating from copyleft. It's not the same thing... copyleft code is out in the open on purpose, with the condition that you share back in kind. People are latching onto the intellectual property angle of this article, but the point is way simpler than that: "The terms of that compact were: if you take this and build on it, you share back under the same terms."</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317021"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=panny" class="hnuser">panny</a> <a href="https://news.ycombinator.com/item?id=47317021">3 days ago</a> | <a href="#47320195" class="clicky" aria-hidden="true">prev</a> | <a href="#47314451" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Both sides are wrong on this actually. Computer generated code has no copyright protection.
<p>&gt;The U.S. Copyright Office (USCO) and federal courts have consistently ruled that AI-generated works—where the expressive elements are determined by the machine, even in response to a human prompt—lack the necessary human creative input and therefore cannot be copyrighted.</p>
<p>All this code is public domain. Your employees can publish "your" AI generated code freely and it won't matter how many tokens you spent generating it. It is not covered by copyright.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314451"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=svilen_dobrev" class="hnuser">svilen_dobrev</a> <a href="https://news.ycombinator.com/item?id=47314451">3 days ago</a> | <a href="#47317021" class="clicky" aria-hidden="true">prev</a> | <a href="#47324384" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">i've been following this for a while.. and the trend for copyright (of any form - books code pictures music whatever) being laundered by reinventing the "same" thing in-some-way.. is kind-of clear.
<p>But what happens with the <em>new</em> things? Has the era of software-making (or creating things at large) finished, and from now on everything will be re-(gurgitated|implemented|polished) old stuff?</p>
<p>Or all goes back to proprietary everything.. Babylon-tower style, noone talks to noone?</p>
<p>edit: another view - is open-source from now on only for resume-building? "see-what-i've-built" style</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324384"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jpauline" class="hnuser">jpauline</a> <a href="https://news.ycombinator.com/item?id=47324384">2 days ago</a> | <a href="#47314451" class="clicky" aria-hidden="true">prev</a> | <a href="#47312808" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm specifically worried about gating trained data where publicly accessible information is blocked/opted-out. If we're opening up Pandora's Box with genAI and training data, we may as well give it what is accessible to the average user. Its going to end up having the same issues a user with implicit knowledge or memories would have anyway.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312808"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=danbruc" class="hnuser">danbruc</a> <a href="https://news.ycombinator.com/item?id=47312808">3 days ago</a> | <a href="#47324384" class="clicky" aria-hidden="true">prev</a> | <a href="#47317267" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Why are people even having problems with sharing their changes to begin with? Just publishing it somewhere does not seem too expensive. The risk of accidentally including stuff that is not supposed to become public? Or are people regularly completely changing codebases and do not want to make the effort freely available, maybe especially to competitors? I would have assumed that the common case is adding a missing feature here, tweaking something there, if you turn the entire thing on its head, why not have your own alternative solution from scratch?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317267"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ball_of_lint" class="hnuser">ball_of_lint</a> <a href="https://news.ycombinator.com/item?id=47317267">3 days ago</a> | <a href="#47312808" class="clicky" aria-hidden="true">prev</a> | <a href="#47311802" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Would software be more or less free in a world without copyright?
<p>I argue more free. EULAs and restrictions on how+for what software can be used, like DRM, typically use copyright as their legal backing. GPL licenses turn that on it's head but that doesn't redeem the original, flawed, law.</p>
<p>This seems to follow the letter but not the spirit of the license. If this does pass legal muster, we can do the same to whatever proprietary software we wish, which makes a dramatically different but IMO better ecosystem in the end.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318645"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=duskdozer" class="hnuser">duskdozer</a> <a href="https://news.ycombinator.com/item?id=47318645">2 days ago</a> | <a href="#47317267" class="clicky" aria-hidden="true">parent</a> | <a href="#47311802" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It will be disproportionately hard to do it to proprietary software though. The imbalance of power is sort of what the GPL was there for</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311802"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=dwroberts" class="hnuser">dwroberts</a> <a href="https://news.ycombinator.com/item?id=47311802">3 days ago</a> | <a href="#47317267" class="clicky" aria-hidden="true">prev</a> | <a href="#47317258" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">One of the things that irks me about this whole thing is, if it’s so clean room and distinct, why make the changes to the existing project? Why not make an entirely new library?
<p>The answer to that, I think, is that the authors wanted to squat an existing successful project and gain a platform from it. Hence we have news cycle discussing it.</p>
<p>Nobody cares about a new library using AI, but squash an existing one with this stuff, and you get attention. It’s the reputation, the GitHub stars, whatever</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312061"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=nicole_express" class="hnuser">nicole_express</a> <a href="https://news.ycombinator.com/item?id=47312061">3 days ago</a> | <a href="#47311802" class="clicky" aria-hidden="true">parent</a> | <a href="#47312149" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I mean, Blanchard was the longtime maintainer of chardet already, and had wanted to relicense it for years. So I think that complicates your picture of "squatting an existing successful project".
<p>Honestly it's a weird test case for this sort of thing. I don't think you'd see an equivalent in most open source projects.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312149"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=intrasight" class="hnuser">intrasight</a> <a href="https://news.ycombinator.com/item?id=47312149">3 days ago</a> | <a href="#47311802" class="clicky" aria-hidden="true">parent</a> | <a href="#47312061" class="clicky" aria-hidden="true">prev</a> | <a href="#47317258" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I agree. But you can't copyright goodwill and reputation. Trademark does provide some protection there, right?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317258"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ajross" class="hnuser">ajross</a> <a href="https://news.ycombinator.com/item?id=47317258">3 days ago</a> | <a href="#47311802" class="clicky" aria-hidden="true">prev</a> | <a href="#47316944" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">This take, which I've seen in a few different places now, seems 100% bonkers. A world where anyone can cheaply reimplement anyone else's software and use it on hardware of their own choosing in their own designs and for their own purposes <em>is a free software utopia</em>.
<p>This isn't a problem, this is the goal. GNU was born when RMS couldn't use a printer the way he wanted because of an unmodifiable proprietary driver. That kind of thing just won't happen in the vibe coded future.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318712"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=duskdozer" class="hnuser">duskdozer</a> <a href="https://news.ycombinator.com/item?id=47318712">2 days ago</a> | <a href="#47317258" class="clicky" aria-hidden="true">parent</a> | <a href="#47316944" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It's not going to be like that for proprietary software. All this future ends with is "totally free" software that companies will leech off of in their "totally locked down" software. I guarantee you that people wouldn't have had this reaction if someone had instead replicated Windows from leaked source. Well, other than Microsoft owners/employees.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316944"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=stagger87" class="hnuser">stagger87</a> <a href="https://news.ycombinator.com/item?id=47316944">3 days ago</a> | <a href="#47317258" class="clicky" aria-hidden="true">prev</a> | <a href="#47320052" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm probably spitting in the wind, but stuff like this is why I removed all my hosted open source projects. I manage several niche projects that I have now converted to binary only releases (to almost no push back). It's niche enough that it's not very hard to get LLMs to output chunks of code that it managed to scrape before I took it offline. I don't see many people talking about this angle, but LLMs ripping off my work killed my open source efforts.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47329254"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47329254">2 days ago</a> | <a href="#47316944" class="clicky" aria-hidden="true">parent</a> | <a href="#47320052" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt;I don't see many people talking about this angle, but LLMs ripping off my work killed my open source efforts.
<p>This is <em>exactly</em> what the article is talking about.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47320052"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=niemandhier" class="hnuser">niemandhier</a> <a href="https://news.ycombinator.com/item?id=47320052">2 days ago</a> | <a href="#47316944" class="clicky" aria-hidden="true">prev</a> | <a href="#47312109" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Look at sqllite. They have a good example going how code can be open and you still have a product.
<p>For SQLite the actual product is the test-suite and the audits.</p>
<p>Sure you can use the code all you like, but you only ever get past quality gates if you use the audited and provably tested version.</p>
<p>This becomes just more relevant in the age of ai coding, where an agent might be able to reimplement your specs.</p>
<p>Keep your code open, but consider moving your tests.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312109"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=t43562" class="hnuser">t43562</a> <a href="https://news.ycombinator.com/item?id=47312109">3 days ago</a> | <a href="#47320052" class="clicky" aria-hidden="true">prev</a> | <a href="#47316513" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Why does anyone need his new library? They can do what he did and make their own.
<p>I'm glad we can fork things at a point and thumb our noses at those who wish to cash in on other's work.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312418"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=warkdarrior" class="hnuser">warkdarrior</a> <a href="https://news.ycombinator.com/item?id=47312418">3 days ago</a> | <a href="#47312109" class="clicky" aria-hidden="true">parent</a> | <a href="#47317536" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Why would I make my own? The new library is released under MIT license and faster than the old one.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312586"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=t43562" class="hnuser">t43562</a> <a href="https://news.ycombinator.com/item?id=47312586">3 days ago</a> | <a href="#47312109" class="clicky" aria-hidden="true">root</a> | <a href="#47312418" class="clicky" aria-hidden="true">parent</a> | <a href="#47317536" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If you decide to improve it in any way to fit your needs you can merely tell your own AI to re-implement it with your changes. Then it's proprietary to you.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317536"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47317536">3 days ago</a> | <a href="#47312109" class="clicky" aria-hidden="true">parent</a> | <a href="#47312418" class="clicky" aria-hidden="true">prev</a> | <a href="#47316513" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Consider it an LLM cache. The result has already been cached so you don't have to generate it again.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316513"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=josalhor" class="hnuser">josalhor</a> <a href="https://news.ycombinator.com/item?id=47316513">3 days ago</a> | <a href="#47312109" class="clicky" aria-hidden="true">prev</a> | <a href="#47312531" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think the direction we are going, the GPL is going to fade away. I think people will look at this like writing a book and claiming the ideas in the book cannot be copied. This debate is not that different from the ones going on in the music industry. I open sourced my latest software as Apache 2.0 after debating a lot about this. Unless the FSF wins in court in the next &lt;=2-3 years, there is no coming back from this.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317605"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=0x457" class="hnuser">0x457</a> <a href="https://news.ycombinator.com/item?id=47317605">3 days ago</a> | <a href="#47314108" class="clicky" aria-hidden="true">prev</a> | <a href="#47315479" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Antirez does not address this directional difference. He invokes the GNU precedent, but that precedent is a counterexample to his conclusion, not a supporting one.
<p>Morally - yes, technically - no. I think it's odd to be mad at someone doing the exact thing you praise in another case just because license isn't copyleft within license allowance. Make a better copyleft license?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315479"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=arjie" class="hnuser">arjie</a> <a href="https://news.ycombinator.com/item?id=47315479">3 days ago</a> | <a href="#47317605" class="clicky" aria-hidden="true">prev</a> | <a href="#47317941" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Well, the license change sounds pretty strange, but to be honest if I were to use this software I would use it without adhering to the MIT. It's machine-created content which is not, in general, copyrightable. You can assert whatever license you want on such content, but I am not going to adhere to it. For example, I declare you may use the following under the Elastic License
<pre><code>    The</code></pre></div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317502"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=wvenable" class="hnuser">wvenable</a> <a href="https://news.ycombinator.com/item?id=47317502">3 days ago</a> | <a href="#47315479" class="clicky" aria-hidden="true">parent</a> | <a href="#47317941" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I wonder how one proves that the software is machine created.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318819"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=colmmacc" class="hnuser">colmmacc</a> <a href="https://news.ycombinator.com/item?id=47318819">2 days ago</a> | <a href="#47317941" class="clicky" aria-hidden="true">prev</a> | <a href="#47312333" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">The four essential freedoms of the Free Software movement are ...
<p>1. The freedom to run the program as you wish 2. The freedom to study how it works and modify it (which requires access to source code) 3. The freedom to redistribute copies to help others 4. The freedom to distribute modified versions, so the whole community benefits from your improvements</p>
<p>To my mind ... GenAI coding make all of these far more realizable, especially for "normal people", than CopyLeft ever has. Let's go through them ...</p>
<p>Want to run a program as you wish? Great! It's easier than ever to build a replacement. Proprietary or non-free software is just as vulnerable to reimplementation as Copyleft is.</p>
<p>Want to study a how a program works and to modify it? This is now much more achievable.</p>
<p>Want the freedom to redistribute copies to help others? Build your own version! It may not even be copyrightable if it's 100% generated (IANAL).</p>
<p>Want to distribute modified versions? yes! see previous.</p>
<p>I dunno; seems like generative coding can be as much a liberator as any kind of problem.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318930"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=skydhash" class="hnuser">skydhash</a> <a href="https://news.ycombinator.com/item?id=47318930">2 days ago</a> | <a href="#47318819" class="clicky" aria-hidden="true">parent</a> | <a href="#47318913" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Unless your idea of software is reduced to the set of todo app, I don’t see how your points hold. AI won’t give you Blender, Inkscape, Kicad, Emacs,… And the algorithms behind those are not secrets, it’s the cohesive vision behind the whole system that is hard.
<p>People will still pay for Matlab, SolidWorks, and Maya because no one who need those will vibe-code a solution. And there’s plenty of good OSS versions for the others.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318913"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=alterom" class="hnuser">alterom</a> <a href="https://news.ycombinator.com/item?id=47318913">2 days ago</a> | <a href="#47318819" class="clicky" aria-hidden="true">parent</a> | <a href="#47318930" class="clicky" aria-hidden="true">prev</a> | <a href="#47312333" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Sorry, but this seems to be so off-base (as well as naively optimistic) that I am having difficulty responding to this.
<p>But I'll try nevertheless.</p>
<p>- <em>&gt;Want to run a program as you wish? Great! It's easier than ever to build a replacement.</em></p>
<p>Non-sequitur. <em>Building a replacement</em> does nothing for being able to run a program as you wish.</p>
<p>Nobody else is able to run <em>your</em> program as <em>they</em> wish unless you release it with a Copyleft license.</p>
<p>- <em>&gt;Want to study a how a program works and to modify it? This is now much more achievable.</em></p>
<p><em>Reverse engineering</em> is more achievable.</p>
<p>Modifying a program, without having its source code, documentation, and <em>a legal right to do so</em> guaranteed by the license is (and always be) easier compared to <em>not</em> having those things.</p>
<p>- <em>&gt;Want the freedom to redistribute copies to help others? Build your own version! It may not even be copyrightable if it's 100% generated (IANAL).</em></p>
<p>So, that's not about <em>redistributing copies</em>. That's about building an alternative option.</p>
<p>I <em>can</em> download an Ubuntu image and get Libre Office on it with a click.</p>
<p>Go vibe-code me a Microsoft Excel running on Windows 11, please, and tell me it's easier.</p>
<p>- <em>&gt;Want to distribute modified versions? yes! see previous.</em></p>
<p>You're not even trying here.</p>
<p>One can't legally modify and redistribute copyrighted works without explicit permission to do so.</p>
<p>You keep saying "...but vibe coding allows anyone to create <em>something else entirely instead</em> and do whatever with it!" as if that is a substitute for checking out a repo, or simply <em>downloading</em> FOSS software to use as you wish.</p>
<p>- <em>&gt;I dunno; seems like generative coding can be as much a liberator as any kind of problem.</em></p>
<p>Now, <em>that</em> statement I fully agree with.</p>
<p>Generative coding is a liberator as much as any kind of <em>problem</em> is.</p>
<p>Headache, for example, is generally a problem. It's not a great <em>liberator</em>.</p>
<p>Neither is generative coding.</p>
<p>Now, you probably didn't intend to say what you wrote. And that's exactly why generative coding is not a panacea: the <em>only</em> way to say things that you <em>mean to</em> say is to <em>write</em> precisely what you mean to say.</p>
<p>Vibe-coding (like any vibe-writing) simply can't accomplish that, by design.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312333"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=strongpigeon" class="hnuser">strongpigeon</a> <a href="https://news.ycombinator.com/item?id=47312333">3 days ago</a> | <a href="#47318819" class="clicky" aria-hidden="true">prev</a> | <a href="#47322014" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I feel like the licenses that suffer the most isn't the GPL, but the ones like SSPL. If your code can be re-implemented easily and legally by AWS using an LLM, why risk publishing it?
<p>It does feel like open source is about to change. My hunch is that commercial open source (beyond the consultation model) risks disappearing. Though I'd be happy to be proven wrong.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322014"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=krater23" class="hnuser">krater23</a> <a href="https://news.ycombinator.com/item?id=47322014">2 days ago</a> | <a href="#47312333" class="clicky" aria-hidden="true">prev</a> | <a href="#47324703" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">In Germany we call this 'Beißreflex'. It's all good, when someone reimplements something in Rust, no one asks for the license, but as soon someone uses AI to reimplement something, the search for something to complain about begins.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324703"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=waffletower" class="hnuser">waffletower</a> <a href="https://news.ycombinator.com/item?id=47324703">2 days ago</a> | <a href="#47322014" class="clicky" aria-hidden="true">prev</a> | <a href="#47317147" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I am appreciating the return of the meme "information wants to be free".</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317147"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=api" class="hnuser">api</a> <a href="https://news.ycombinator.com/item?id=47317147">3 days ago</a> | <a href="#47324703" class="clicky" aria-hidden="true">prev</a> | <a href="#47318461" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It also erodes copyright. A decent amount of commercial software can be AI cloned with no copyright violation.
<p>A lot of SaaS too, especially if AI can run a simple deploy.</p>
<p>We might be approaching a huge deflationary catastrophe in the cost of a lot of software. It’s not a catastrophe for the consumer but it is for the industry.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318461"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=ori_b" class="hnuser">ori_b</a> <a href="https://news.ycombinator.com/item?id=47318461">2 days ago</a> | <a href="#47317147" class="clicky" aria-hidden="true">prev</a> | <a href="#47318400" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">If you can prove the LLM was not trained on the code it is reproducing, and has never seen the code as part of a spec to follow, I don't see a problem.
<p>Proving this is going to be hard with current "open source" models.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318508"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eschaton" class="hnuser">eschaton</a> <a href="https://news.ycombinator.com/item?id=47318508">2 days ago</a> | <a href="#47318461" class="clicky" aria-hidden="true">parent</a> | <a href="#47318400" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Indeed, you have to prove that the LLM is <em>generating</em> code <em>from a specification</em>. Right now they don’t do that; what they do is regurgitate portions of their training data based on correlations with input tokens.
<p>Put the programmer’s reference for the Digital Equipment DEQNA QBus Ethernet adapter in your favorite slop tool and tell it to make a C or C++ implementation for an emulator, and you know what you get? Code from SIMH. That’s not “generating,” that’s “copying.”</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318400"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=daemin" class="hnuser">daemin</a> <a href="https://news.ycombinator.com/item?id=47318400">2 days ago</a> | <a href="#47318461" class="clicky" aria-hidden="true">prev</a> | <a href="#47316020" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">One main thing that this brings to mind is if an LLM can ever actually create a clean room implementation of a piece of open source software, given that there is a near certainty that the software was used in its training data. Therefore it has seen it and remembered it, and could if appropriately prompted recreate the code verbatim.
<p>This can also apply to people, either if they have seen the code previously and therefore are ineligible to write the code for a clean-room implementation, or it gets murky when the same person writes the same code twice from their own knoeldge, as in the Oracle Java case.</p>
<p>Coming from a professional programming perspective I can totally see the desire to have more libraries written in permissive licences like BSD or MIT, as they allow one like myself to include them in commercial closed-source products without needing to open source the entire codebase.</p>
<p>However I find myself agreeing with the article in so far as this LLM generated implementation is breaking the social contract for a GPL/LGPL based library. The author could have easily implemented the new version as a separate project and there would not have been an outcry, but because they are replacing the GPL version with this new one it feels scummy to say the least.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316020"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=winstonwinston" class="hnuser">winstonwinston</a> <a href="https://news.ycombinator.com/item?id=47316020">3 days ago</a> | <a href="#47318400" class="clicky" aria-hidden="true">prev</a> | <a href="#47319529" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Blanchard's account is that he never looked at the existing source code directly.
<p>That’s a weird statement while releasing the new version of the same project. Maybe just release it as a new project, chardet-ai v1.0 or whatever.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319529"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=xbar" class="hnuser">xbar</a> <a href="https://news.ycombinator.com/item?id=47319529">2 days ago</a> | <a href="#47316020" class="clicky" aria-hidden="true">prev</a> | <a href="#47318994" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Oracle v Google concluded that APIs could not be protected by either copyright or copyleft. It seemed to me at the time that most here supported that decision. Has anything changed?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47321516"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vbarrielle" class="hnuser">vbarrielle</a> <a href="https://news.ycombinator.com/item?id=47321516">2 days ago</a> | <a href="#47319529" class="clicky" aria-hidden="true">parent</a> | <a href="#47318994" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">No, APIs fall under copyright, but the Supreme Court found that Google's reimplementation of Java's API was falling under fair use. Fair use is decided case by case, one cannot use that decision as a precedent.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318994"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=tw1984" class="hnuser">tw1984</a> <a href="https://news.ycombinator.com/item?id=47318994">2 days ago</a> | <a href="#47319529" class="clicky" aria-hidden="true">prev</a> | <a href="#47312190" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Claude must be trained on chardet already, it worked on chardet's code to optimize or rewrite it to be much better. This is the textbook definition of derivative works.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322095"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=krater23" class="hnuser">krater23</a> <a href="https://news.ycombinator.com/item?id=47322095">2 days ago</a> | <a href="#47318994" class="clicky" aria-hidden="true">parent</a> | <a href="#47312190" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">There is fewer then 2% of code a copy of chardet. When the developer of chardet had done it without AI, whats then? He is trained on the same code too.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312190"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=sayrer" class="hnuser">sayrer</a> <a href="https://news.ycombinator.com/item?id=47312190">3 days ago</a> | <a href="#47318994" class="clicky" aria-hidden="true">prev</a> | <a href="#47314380" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I don't think this part is correct: "If you distribute modified code, <em>or offer it as a networked service</em>, you must make the source available under the same terms."
<p>That's what something like AGPL does.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314380"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=moralestapia" class="hnuser">moralestapia</a> <a href="https://news.ycombinator.com/item?id=47314380">3 days ago</a> | <a href="#47312190" class="clicky" aria-hidden="true">prev</a> | <a href="#47317201" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">That's a non-sequitur. chardet v7 is GPL-derived work (currently in clear violation of the GPL). If xe wanted it to be a different thing xe should've published as such. Simple as.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317201"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hungryhobbit" class="hnuser">hungryhobbit</a> <a href="https://news.ycombinator.com/item?id=47317201">3 days ago</a> | <a href="#47314380" class="clicky" aria-hidden="true">prev</a> | <a href="#47316663" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">I largely agree with the author that AI can't just magically remove license agreements by rewriting code.
<p>However, I take issue with his version of history:</p>
<p>&gt;The history of the GPL is the history of licensing tools evolving in response to new forms of exploitation: GPLv2 to GPLv3, then AGPL.</p>
<p>GPLv3 set open source backwards: it wasn't an evolution to protect anything, it was a an overly paranoid failure. Don't believe me? Just count how many GPL3 vs. how many GPL2 projects have been started since GPL3 dropped.</p>
<p>Again, I'm very pro-OSS, but let's not pretend the community has always had a straight line of progress forward; some stuff is crazy Stallman stuff that set us back.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316917"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=randyrand" class="hnuser">randyrand</a> <a href="https://news.ycombinator.com/item?id=47316917">3 days ago</a> | <a href="#47316663" class="clicky" aria-hidden="true">prev</a> | <a href="#47315764" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">It doesn't matter if it's legitimate. The people that use it don't care. They just find it online and click download. This is the reality.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315764"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=kanemcgrath" class="hnuser">kanemcgrath</a> <a href="https://news.ycombinator.com/item?id=47315764">3 days ago</a> | <a href="#47316917" class="clicky" aria-hidden="true">prev</a> | <a href="#47315490" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">without discussing copyright, I don't believe any of this is copied. Which I think should be the argument that actually matters.
<p>I downloaded both 6.0 and 7.0 and based on only a light comparison of a few key files, nothing would suggest to me that 7.0 was copied from 6.0, especially for a 41x faster implementation. It is a lot more organized and readable in my armature opinion, and the code is about 1/10th the size.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315490"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=iberator" class="hnuser">iberator</a> <a href="https://news.ycombinator.com/item?id=47315490">3 days ago</a> | <a href="#47315764" class="clicky" aria-hidden="true">prev</a> | <a href="#47318214" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Easy solution for now:
<p>Add something like this to NEW gpl /bsd/mit licenses:</p>
<p>'you are forbidden from reimplementing it with AI'</p>
<p>or just:</p>
<p>'all clones, reimpletetions with ai etc must still be GPL'</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47318214"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=keeda" class="hnuser">keeda</a> <a href="https://news.ycombinator.com/item?id=47318214">3 days ago</a> | <a href="#47315490" class="clicky" aria-hidden="true">prev</a> | <a href="#47323296" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">A large part of our industry is experiencing significant cognitive dissonance and articles like this are a symptom of that. AI is not really changing things, it's simply forcing us to question a lot of things we took for granted.
<p>One of those things is that we assumed that the <em>code</em> embodied most of the value it offered. That it was the code that contained the creativity and expressiveness and usefulness. And we thought only we could write code. And so we thought we only needed to protect the code to protect our efforts and investments. Which is also why we accepted copyright as an appropriate legal protection for software, or of enforcing an ethos of sharing, as with copyleft.</p>
<p>But the code itself was never the valuable aspect; it was the <em>functionality it provided</em>.</p>
<p>And now AI is making that starkly apparent, while undermining a lot of other presumptions. Including about copyright.</p>
<p>Copyright protection for software is a historical hack because people didn’t want to figure out an appropriate legal framework from scratch. You “wrote” books, you "wrote" code, let’s shoehorn software into copyright and go get lunch! Completely overlooking the fact that copyright explicitly does not cover <em>functional aspects</em> (that is the realm of patents) which is the entire raison d'etre of code.</p>
<p>Sure, copyright covers “expressive elements”, but again those are properties of the source code, not the functionality. In fact, expressiveness is BAD for code (cf “code should be boring”)! Copyright will protect whether you used a streams API or a for-loop for iteration, which is absolutely irrelevant to the technical functionality that actually solves user problems, which has always been the <em>only</em> thing users really cared about.</p>
<p>In fact, if you look at significant copyright-related cases for software now (e.g. Oracle vs Google), you'll realize they have twisted themselves into knots trying to apply laws intended for expressive creativity to issues that were essentially about technical creativity.</p>
<p>I have no hopes that we will figure out an appropriate IP framework for software, so I expect people will move towards other things like patents, trade secrets and trademarks. Which have their own problems, but at least they already exist and are more suitable than copyright, especially in the age of AI.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47323296"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=jFriedensreich" class="hnuser">jFriedensreich</a> <a href="https://news.ycombinator.com/item?id=47323296">2 days ago</a> | <a href="#47318214" class="clicky" aria-hidden="true">prev</a> | <a href="#47314146" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">I wonder what value gpl even has in a world where i can trivially reimplement whatever a company builds on a permissive license and does not share. I see still a place for things that are low level, algo heavy, real world test heavy and critical eg. kernel, cryptography, storage engine, filesystems all the rest of userland and web not so much</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314146"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mh2266" class="hnuser">mh2266</a> <a href="https://news.ycombinator.com/item?id=47314146">3 days ago</a> | <a href="#47323296" class="clicky" aria-hidden="true">prev</a> | <a href="#47312551" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Buried in here: Mark Pilgrim suddenly reappearing after his sudden disappearance years ago! Has he been up to anything since then?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312551"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mwkaufma" class="hnuser">mwkaufma</a> <a href="https://news.ycombinator.com/item?id=47312551">3 days ago</a> | <a href="#47314146" class="clicky" aria-hidden="true">prev</a> | <a href="#47313062" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">A lot of untagged IANAL takes here today.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313062"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=hexyl_C_gut" class="hnuser">hexyl_C_gut</a> <a href="https://news.ycombinator.com/item?id=47313062">3 days ago</a> | <a href="#47312551" class="clicky" aria-hidden="true">prev</a> | <a href="#47315761" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm less concerned about AI eroding copyleft and more exited about AI eroding copy right.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315761"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=animitronix" class="hnuser">animitronix</a> <a href="https://news.ycombinator.com/item?id=47315761">3 days ago</a> | <a href="#47313062" class="clicky" aria-hidden="true">prev</a> | <a href="#47311915" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">LPGL is dead, long live the AI rewrites of your barely open source code</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311915"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway2027" class="hnuser">throwaway2027</a> <a href="https://news.ycombinator.com/item?id=47311915">3 days ago</a> | <a href="#47315761" class="clicky" aria-hidden="true">prev</a> | <a href="#47319445" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Perhaps software patents may play an even bigger role in the future.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312181"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=intrasight" class="hnuser">intrasight</a> <a href="https://news.ycombinator.com/item?id=47312181">3 days ago</a> | <a href="#47311915" class="clicky" aria-hidden="true">parent</a> | <a href="#47319445" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Or, hopefully, even less of a role.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319445"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=eduction" class="hnuser">eduction</a> <a href="https://news.ycombinator.com/item?id=47319445">2 days ago</a> | <a href="#47311915" class="clicky" aria-hidden="true">prev</a> | <a href="#47316344" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Despite the tech layoffs and rise of AI, programmer hubris is alive and well, that is heartening.
<p>Here we see three engineers writing — at length! — about a hugely complicated matter of law.</p>
<p>No one outside your bubble cares what you think. You are unqualified and your opinions irrelevant. You might as well be debating open heart surgery techniques.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47316344"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=palata" class="hnuser">palata</a> <a href="https://news.ycombinator.com/item?id=47316344">3 days ago</a> | <a href="#47319445" class="clicky" aria-hidden="true">prev</a> | <a href="#47317843" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; an argument for protecting that test suite and API specification under copyleft terms.
<p>If we protect API under copyright, it makes it easier to prevent interoperability. We obviously do NOT want that. It would give big companies even more power.</p>
<p>Now in the US, the Supreme Court that the output of an LLM is not copyrightable. So even a permissive licence doesn't work for that reimplementation: it should be public domain.</p>
<p>Disclaimer: I am all for copyleft for the code I write, but already without LLMs, one could rewrite a similar project and use the licence they please. LLMs make them faster at that, it's just a fact.</p>
<p>Now I wonder: say I vibe-code a library (so it's public domain in the US), I don't publish that code but I sell it to a customer. Can I prevent them from reselling it? I guess not, since it's public domain?</p>
<p>And as an employee writing code for a company. If I produce public domain code because it is written by an LLM, can I publish it, or can the company prevent me from doing it?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47317843"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=internet2000" class="hnuser">internet2000</a> <a href="https://news.ycombinator.com/item?id=47317843">3 days ago</a> | <a href="#47316344" class="clicky" aria-hidden="true">prev</a> | <a href="#47313555" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I stopped reading here:
<p>&gt; The ethical force of that project did not come from its legal permissibility—it came from the direction it was moving, from the fact that it was expanding the commons. That is why people cheered.</p>
<p>How is this not just relitigating GPL vs MIT? By now you know which side of that argument you are in. The AI component is orthogonal.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47313555"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Khaine" class="hnuser">Khaine</a> <a href="https://news.ycombinator.com/item?id=47313555">3 days ago</a> | <a href="#47317843" class="clicky" aria-hidden="true">prev</a> | <a href="#47323114" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Someone be brave, and do this to ZFS. Poke the Oracle bear!</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47322085"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=krater23" class="hnuser">krater23</a> <a href="https://news.ycombinator.com/item?id=47322085">2 days ago</a> | <a href="#47313555" class="clicky" aria-hidden="true">parent</a> | <a href="#47323114" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Please don't. I don't trust AI code when we talk about my filesystem and data.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47331714"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Khaine" class="hnuser">Khaine</a> <a href="https://news.ycombinator.com/item?id=47331714">1 day ago</a> | <a href="#47313555" class="clicky" aria-hidden="true">root</a> | <a href="#47322085" class="clicky" aria-hidden="true">parent</a> | <a href="#47323114" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I meant it as a joke, given that oracle is famously litigious. It would solve the legal questions</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47323114"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=pie_flavor" class="hnuser">pie_flavor</a> <a href="https://news.ycombinator.com/item?id=47323114">2 days ago</a> | <a href="#47313555" class="clicky" aria-hidden="true">prev</a> | <a href="#47315326" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">While no fan of AI slop, is there any difference between this and musl/busybox/etc, minus the addition of AI? Did anyone get mad at busybox before AI?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315326"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mbgerring" class="hnuser">mbgerring</a> <a href="https://news.ycombinator.com/item?id=47315326">3 days ago</a> | <a href="#47323114" class="clicky" aria-hidden="true">prev</a> | <a href="#47324156" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">See also "A Declaration of the Independence of Cyberspace" (<a href="https://www.eff.org/cyberspace-independence" rel="nofollow">https://www.eff.org/cyberspace-independence</a>), and what a goofy, naive, misguided disaster that early internet optimism turned into.
<p>No, AI does not mean the end of either copyright or copyleft, it means that the laws need to catch up. And they should, and they will.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47324156"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=youknownothing" class="hnuser">youknownothing</a> <a href="https://news.ycombinator.com/item?id=47324156">2 days ago</a> | <a href="#47315326" class="clicky" aria-hidden="true">prev</a> | <a href="#47311773" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Theseus ship, anyone?</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311773"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mfabbri77" class="hnuser">mfabbri77</a> <a href="https://news.ycombinator.com/item?id=47311773">3 days ago</a> | <a href="#47324156" class="clicky" aria-hidden="true">prev</a> | <a href="#47311823" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">What if someone doesn't declare that it has been reimplemented using an LLM? Isn't it enough to simply declare that you have reimplemented the software without using an LLM? Good luck proving that in court...
<p>One thing is certain, however: copyleft licenses will disappear: If I can't control the redistribution of my code (through a GPL or similar license), I choose to develop it in closed source.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311985"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=bigyabai" class="hnuser">bigyabai</a> <a href="https://news.ycombinator.com/item?id=47311985">3 days ago</a> | <a href="#47311773" class="clicky" aria-hidden="true">parent</a> | <a href="#47311823" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Arguably, the GPL has always been the wrong choice if you want to authoritatively control redistribution.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311823"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=delichon" class="hnuser">delichon</a> <a href="https://news.ycombinator.com/item?id=47311823">3 days ago</a> | <a href="#47311773" class="clicky" aria-hidden="true">prev</a> | <a href="#47311772" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c5A">Imagine if the author has his way, and when we have AI write software, it becomes legally under the license of some other sufficiently similar piece of software. Which may or may not be proprietary. "I see you have generated a todo app very similar to Todoist. So they now own it." That does not seem like a good path either for open source software or for opening up the benefits of AI generated software.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311772"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throawayonthe" class="hnuser">throawayonthe</a> <a href="https://news.ycombinator.com/item?id=47311772">3 days ago</a> | <a href="#47311823" class="clicky" aria-hidden="true">prev</a> | <a href="#47315559" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">shall we now have to think about the tradeoffs in adopting
<p>- proprietary</p>
<p>- free</p>
<p>- slop-licensed</p>
<p>software?</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315786"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=megous" class="hnuser">megous</a> <a href="https://news.ycombinator.com/item?id=47315786">3 days ago</a> | <a href="#47311772" class="clicky" aria-hidden="true">parent</a> | <a href="#47315559" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">We should just use LLMs to free more software and HW. Make it work against the system.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311893"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=logicprog" class="hnuser">logicprog</a> <a href="https://news.ycombinator.com/item?id=47311893">3 days ago</a> | <a href="#47315559" class="clicky" aria-hidden="true">prev</a> | <a href="#47319034" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; Ronacher notes this as an irony and moves on. But the irony cuts deeper than he lets on. Next.js is MIT licensed. Cloudflare's vinext did not violate any license—it did exactly what Ronacher calls a contribution to the culture of openness, applied to a permissively licensed codebase. Vercel's reaction had nothing to do with license infringement; it was purely competitive and territorial. The implicit position is: reimplementing GPL software as MIT is a victory for sharing, but having our own MIT software reimplemented by a competitor is cause for outrage. This is what the claim that permissive licensing is “more share-friendly” than copyleft looks like in practice. The spirit of sharing, it turns out, runs in one direction only: outward from oneself.
<p>This argument makes no sense. Are they arguing that because Vercel, specifically, had this attitude, this is an attitude necessitated by AI, reimplementation, and those who are in favor of it towards more permissive licenses? That certainly doesn't seem to be an accurate way to summarize what antirez or Ronacher believe. In fact, under the legal and ethical frameworks (respectively) that those two put forward, Vercel has no right to claim that position and no way to enforce it, so it seems very strange to me to even assert that this sort of thing would be the <em>practical</em> result of AI reimplementations. This seems to just be pointing towards the hypocrisy of one particular company, and assuming that this would be the inevitable universal, attitude, and result when there's no evidence to think so.</p>
<p>It's ironic, because antirez actually literally addresses this specific argument. They completely miss the fact that a lot of his blog post is not actually just about legal but also about ethical matters. Specifically, the idea he puts forward is that yes, corporations can do these kinds of rewrites now, but they always had the resources and manpower to do so anyway. What's different now is that individuals can do this kind of rewrites when they never have the ability to do so before, and the vector of such a rewrite can be from a permissive to copyleft or even from decompile the proprietary to permissive or copyleft. The fact that it hasn't been so far is a more a factor of the fact that most people really hate copyleft and find an annoying and it's been losing traction and developer mind share for decades, not that this tactic can't be used that way. I think that's actually one of the big points he's trying to make with his GNU comparison — not just that if it was legal for GNU to do it, then it's legal for you to do with AI, and not even just the fundamental libertarian ethical axiom (that I agree with for the most part) that it should remain legal to do such a rewrite in either direction because in terms of the fundamental axioms that we enforce with violence in our society, there should be a level playing field where we look at the action itself and not just whether we like or dislike the consequences, but specifically the fact that if GNU did it once with the ability to rewrite things, it can be done again, even in the same direction, it now even more easily using AI.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312067"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=antirez" class="hnuser">antirez</a> <a href="https://news.ycombinator.com/item?id=47312067">3 days ago</a> | <a href="#47311893" class="clicky" aria-hidden="true">parent</a> | <a href="#47312200" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">&gt; They completely miss the fact that a lot of his blog post is not actually just about legal but also about ethical matters.
<p>Honestly I was confused about the summarization of my blog post into just a legal matter as well. I hope my blog post will be able to flash at least a short time in the HN front page so that the actual arguments it contain will get a bit more exposure.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312200"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=Talanes" class="hnuser">Talanes</a> <a href="https://news.ycombinator.com/item?id=47312200">3 days ago</a> | <a href="#47311893" class="clicky" aria-hidden="true">parent</a> | <a href="#47312067" class="clicky" aria-hidden="true">prev</a> | <a href="#47319034" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I'm failing to see what in the quoted text you took to be about AI rewrites specifically? It just reads as a slightly catty aside about the social reaction of rewrites in general (by implying the one example is generalizable.)</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47319034"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=antonio-mello" class="hnuser">antonio-mello</a> <a href="https://news.ycombinator.com/item?id=47319034">2 days ago</a> | <a href="#47311893" class="clicky" aria-hidden="true">prev</a> | <a href="#47317225" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">The practical tension I see: I build open source tools and use AI heavily in the process (Claude as a coding assistant). Every commit has "Co-Authored-By: Claude" in it. The code is MIT-licensed and genuinely mine in terms of architecture and intent, but the line-by-line generation is clearly AI-assisted.
<p>This creates an odd situation where the "reimplementation via AI" concern cuts both ways. If someone feeds my MIT repo to an LLM and gets a copyleft-violating derivative, that's one problem. But if I use an LLM trained on copyleft code to write my MIT-licensed tool, am I the one laundering licenses without knowing it?</p>
<p>I think the article's core point holds: legitimacy and legality are diverging fast. The open source community built norms around intent and reciprocity, and those norms are now being stress-tested by tools that can reimplement anything from a spec. No license text can fully encode "don't be a free rider."</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311860"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=moi2388" class="hnuser">moi2388</a> <a href="https://news.ycombinator.com/item?id=47311860">3 days ago</a> | <a href="#47312145" class="clicky" aria-hidden="true">prev</a> | <a href="#47311732" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">Perhaps we should finally admit that copyright has always been nonsense, and abolish this ridiculous measure once and for all</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311949"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=vladms" class="hnuser">vladms</a> <a href="https://news.ycombinator.com/item?id=47311949">3 days ago</a> | <a href="#47311860" class="clicky" aria-hidden="true">parent</a> | <a href="#47314688" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Probably a wiser approach is to consider different times require different measures (in general!).
<p>I did not study in detail if copyright "has always been nonsense", but I do agree that nowadays some of the copyright regulations are nonsense (for example the very long duration of life + 70 years)</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47314688"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=joshmoody24" class="hnuser">joshmoody24</a> <a href="https://news.ycombinator.com/item?id=47314688">3 days ago</a> | <a href="#47311860" class="clicky" aria-hidden="true">parent</a> | <a href="#47311949" class="clicky" aria-hidden="true">prev</a> | <a href="#47312264" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">IMO the core idea of copyright isn't nonsense, but I do think the current implementation (70+ years after death) is egregiously overpowered. I've always thought the current laws were too deeply entrenched to ever change, but I'm tentatively optimistic AI will shock the system hard enough to trigger actual reform.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312264"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=intrasight" class="hnuser">intrasight</a> <a href="https://news.ycombinator.com/item?id=47312264">3 days ago</a> | <a href="#47311860" class="clicky" aria-hidden="true">parent</a> | <a href="#47314688" class="clicky" aria-hidden="true">prev</a> | <a href="#47315376" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">I think AI is very much eroding the legitimacy of copyright - at least to software, which is long been questioned since it's more like math than creative expression.
<p>I think the industry will realize that it made a huge mistake by leaning on copyright for protection rather than on patents.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47315376"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=mbgerring" class="hnuser">mbgerring</a> <a href="https://news.ycombinator.com/item?id=47315376">3 days ago</a> | <a href="#47311860" class="clicky" aria-hidden="true">parent</a> | <a href="#47312264" class="clicky" aria-hidden="true">prev</a> | <a href="#47311732" class="clicky" aria-hidden="true">next</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">Actually I think the last 20 years of the Internet demonstrates that copyright is more important than ever, because unless it's enforced, people with more capital than the copyright owner will simply steal creative works and profit from them.
<p>The idea that "information wants to be free" was always a lie, meant to transfer value from creators to platform owners. The result of that has been disastrous, and it's long past time to push the pendulum in the other direction.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311732"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="0" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=throwaway2027" class="hnuser">throwaway2027</a> <a href="https://news.ycombinator.com/item?id=47311732">3 days ago</a> | <a href="#47311860" class="clicky" aria-hidden="true">prev</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c73">I think we're going one step too far even, AI itself is a gray area and how can they guarantee it was trained legally or if it's even legal what they're doing and how can they assert that the input training data didn't contain any copyrighted data.</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47311906"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="40" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=observationist" class="hnuser">observationist</a> <a href="https://news.ycombinator.com/item?id=47311906">3 days ago</a> | <a href="#47311732" class="clicky" aria-hidden="true">parent</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Google already spent billions of dollars and decades of lawyer hours proving it out as fair use. The legal challenges we see now are the dying convulsions of an already broken system of publishers and IP hoarders using every resource at their disposal to manipulate authors and creators and the public into thinking that there's any legitimacy or value underlying modern copyright law.
<p>AI will destroy the current paradigm, completely and utterly, and there's nothing they can do to stop it. It's unclear if they can even slow it, and that's a good thing.</p>
<p>We will be forced to legislate a modern, digital oriented copyright system that's fair and compatible with AI. If producing any software becomes a matter of asking a machine to produce it - if things like AI native operating systems come about, where apps and media are generated on demand, with protocols as backbone, and each device is just generating its own scaffolding around the protocols - then nearly none of modern licensing, copyright, software patents, or IP conventions make any sense whatsoever.</p>
<p>You can't have horse and buggy traffic conventions for airplanes. We're moving in to a whole new paradigm, and maybe we can get legislation that actually benefits society and individuals, instead of propping up massive corporations and making lawyers rich.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr><tr class="athing comtr" id="47312388"><td>
<table border="0"><tr><td class="ind"><img src="https://news.ycombinator.com/s.gif" height="1" width="80" alt="image" /></td>
<td valign="top" class="votelinks">
<div class="c7">
</div></td>
<td class="default">
<div class="c8"><a href="https://news.ycombinator.com/user?id=casey2" class="hnuser">casey2</a> <a href="https://news.ycombinator.com/item?id=47312388">3 days ago</a> | <a href="#47311732" class="clicky" aria-hidden="true">root</a> | <a href="#47311906" class="clicky" aria-hidden="true">parent</a> <a class="togg clicky" href="denied:javascript:void(0)">[–]</a></div>
<br /><div class="commdiv">
<div class="commtext c00">Google has cut out some very specific ruling that have nothing to do with modern AI. These systems are just a really slow/lossy git clone, current law has no trouble with it, it's broadly illegal.
<p>If corporations are allowed to launder someone else work as their own people will simply stop working and just start endlessly remixing a la popular music.</p>
</div>
<div class="reply">
<p><span class="c9"></span></p>
</div>
</div>
</td>
</tr></table></td>
</tr></table>]]></description>
      <link>https://news.ycombinator.com/item?id=47310160</link>
      <guid>https://news.ycombinator.com/item?id=47310160</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[ruvnet/RuView: π RuView: WiFi DensePose turns commodity WiFi signals into real-time human pose estimation, vital sign monitoring, and presence detection — all without a single pixel of video.]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">π RuView</h1><a id="user-content-π-ruview" class="anchor" aria-label="Permalink: π RuView" href="#π-ruview"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p align="center" dir="auto">
  <a href="https://ruvnet.github.io/RuView/" rel="nofollow">
    <img src="assets/ruview-small-gemini.jpg" alt="RuView - WiFi DensePose" width="100%" style="max-width: 100%;">
  </a>
</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto"><strong>See through walls with WiFi + Ai</strong></h2><a id="user-content-see-through-walls-with-wifi--ai" class="anchor" aria-label="Permalink: See through walls with WiFi + Ai" href="#see-through-walls-with-wifi--ai"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Perceive the world through signals.</strong> No cameras. No wearables. No Internet. Just physics.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">π RuView is an edge AI perception system that learns directly from the environment around it.</h3><a id="user-content-π-ruview-is-an-edge-ai-perception-system-that-learns-directly-from-the-environment-around-it" class="anchor" aria-label="Permalink: π RuView is an edge AI perception system that learns directly from the environment around it." href="#π-ruview-is-an-edge-ai-perception-system-that-learns-directly-from-the-environment-around-it"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Instead of relying on cameras or cloud models, it observes whatever signals exist in a space such as WiFi, radio waves across the spectrum, motion patterns, vibration, sound, or other sensory inputs and builds an understanding of what is happening locally.</p>
<p dir="auto">Built on top of <a href="https://github.com/ruvnet/ruvector/">RuVector</a>, the project became widely known for its implementation of WiFi DensePose — a sensing technique first explored in academic research such as Carnegie Mellon University's <em>DensePose From WiFi</em> work. That research demonstrated that WiFi signals can be used to reconstruct human pose.</p>
<p dir="auto">RuView extends that concept into a practical edge system. By analyzing Channel State Information (CSI) disturbances caused by human movement, RuView reconstructs body position, breathing rate, heart rate, and presence in real time using physics-based signal processing and machine learning.</p>
<p dir="auto">Unlike research systems that rely on synchronized cameras for training, RuView is designed to operate entirely from radio signals and self-learned embeddings at the edge.</p>
<p dir="auto">The system runs entirely on inexpensive hardware such as an ESP32 sensor mesh (as low as ~$1 per node). Small programmable edge modules analyze signals locally and learn the RF signature of a room over time, allowing the system to separate the environment from the activity happening inside it.</p>
<p dir="auto">Because RuView learns in proximity to the signals it observes, it improves as it operates. Each deployment develops a local model of its surroundings and continuously adapts without requiring cameras, labeled data, or cloud infrastructure.</p>
<p dir="auto">In practice this means ordinary environments gain a new kind of spatial awareness. Rooms, buildings, and devices begin to sense presence, movement, and vital activity using the signals that already fill the space.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Built for low-power edge applications</h3><a id="user-content-built-for-low-power-edge-applications" class="anchor" aria-label="Permalink: Built for low-power edge applications" href="#built-for-low-power-edge-applications"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a href="#edge-intelligence-adr-041">Edge modules</a> are small programs that run directly on the ESP32 sensor — no internet needed, no cloud fees, instant response.</p>
<p dir="auto"><a href="https://www.rust-lang.org/" rel="nofollow"><img src="https://camo.githubusercontent.com/3f9d4c833f08b486080b0d091ad02b8f8459f453abf0888f84ae6f4ca66944a0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f727573742d312e38352b2d6f72616e67652e737667" alt="Rust 1.85+" data-canonical-src="https://img.shields.io/badge/rust-1.85+-orange.svg" style="max-width: 100%;"></a>
<a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT" data-canonical-src="https://img.shields.io/badge/License-MIT-yellow.svg" style="max-width: 100%;"></a>
<a href="https://github.com/ruvnet/RuView"><img src="https://camo.githubusercontent.com/5de55ff655e9aa6243cdad5b1717a3a66fb7162783c54743e098fd679255c6f2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d313330302532422d627269676874677265656e2e737667" alt="Tests: 1300+" data-canonical-src="https://img.shields.io/badge/tests-1300%2B-brightgreen.svg" style="max-width: 100%;"></a>
<a href="https://hub.docker.com/r/ruvnet/wifi-densepose" rel="nofollow"><img src="https://camo.githubusercontent.com/d7a3319bb75a013eed7214b6051e52d009018ff749537efc58ea3cd1f382417c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f636b65722d616d64363425323025324225323061726d36342d626c75652e737667" alt="Docker: multi-arch" data-canonical-src="https://img.shields.io/badge/docker-amd64%20%2B%20arm64-blue.svg" style="max-width: 100%;"></a>
<a href="#vital-sign-detection"><img src="https://camo.githubusercontent.com/4b40a27cfc82a531903762cb7687137b49932418efc498af244f11614f9960f7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f766974616c2532307369676e732d627265617468696e672532302532422532306865617274626561742d7265642e737667" alt="Vital Signs" data-canonical-src="https://img.shields.io/badge/vital%20signs-breathing%20%2B%20heartbeat-red.svg" style="max-width: 100%;"></a>
<a href="#esp32-s3-hardware-pipeline"><img src="https://camo.githubusercontent.com/cb98b430d54f9be266e7c5c1323cc8b0450ec5763d2a34ee4de9129f34a9e57a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f45535033322d2d53332d43534925323073747265616d696e672d707572706c652e737667" alt="ESP32 Ready" data-canonical-src="https://img.shields.io/badge/ESP32--S3-CSI%20streaming-purple.svg" style="max-width: 100%;"></a>
<a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow"><img src="https://camo.githubusercontent.com/33daf0f5f54af17d0193f4e533ddb051455495474682468091ba2f4034fc73a0/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d7275766563746f722e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-ruvector.svg" style="max-width: 100%;"></a></p>
<blockquote>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>What</th>
<th>How</th>
<th>Speed</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Pose estimation</strong></td>
<td>CSI subcarrier amplitude/phase → DensePose UV maps</td>
<td>54K fps (Rust)</td>
</tr>
<tr>
<td><strong>Breathing detection</strong></td>
<td>Bandpass 0.1-0.5 Hz → FFT peak</td>
<td>6-30 BPM</td>
</tr>
<tr>
<td><strong>Heart rate</strong></td>
<td>Bandpass 0.8-2.0 Hz → FFT peak</td>
<td>40-120 BPM</td>
</tr>
<tr>
<td><strong>Presence sensing</strong></td>
<td>RSSI variance + motion band power</td>
<td>&lt; 1ms latency</td>
</tr>
<tr>
<td><strong>Through-wall</strong></td>
<td>Fresnel zone geometry + multipath modeling</td>
<td>Up to 5m depth</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</blockquote>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# 30 seconds to live sensing — no toolchain required
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 ruvnet/wifi-densepose:latest
# Open http://localhost:3000"><pre><span class="pl-c"><span class="pl-c">#</span> 30 seconds to live sensing — no toolchain required</span>
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 ruvnet/wifi-densepose:latest
<span class="pl-c"><span class="pl-c">#</span> Open http://localhost:3000</span></pre></div>
<div class="markdown-alert markdown-alert-note" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-info mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Note</p><p dir="auto"><strong>CSI-capable hardware required.</strong> Pose estimation, vital signs, and through-wall sensing rely on Channel State Information (CSI) — per-subcarrier amplitude and phase data that standard consumer WiFi does not expose. You need CSI-capable hardware (ESP32-S3 or a research NIC) for full functionality. Consumer WiFi laptops can only provide RSSI-based presence detection, which is significantly less capable.</p>
</div>
<blockquote>
<p dir="auto"><strong>Hardware options</strong> for live CSI capture:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Option</th>
<th>Hardware</th>
<th>Cost</th>
<th>Full CSI</th>
<th>Capabilities</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ESP32 Mesh</strong> (recommended)</td>
<td>3-6x ESP32-S3 + WiFi router</td>
<td>~$54</td>
<td>Yes</td>
<td>Pose, breathing, heartbeat, motion, presence</td>
</tr>
<tr>
<td><strong>Research NIC</strong></td>
<td>Intel 5300 / Atheros AR9580</td>
<td>~$50-100</td>
<td>Yes</td>
<td>Full CSI with 3x3 MIMO</td>
</tr>
<tr>
<td><strong>Any WiFi</strong></td>
<td>Windows, macOS, or Linux laptop</td>
<td>$0</td>
<td>No</td>
<td>RSSI-only: coarse presence and motion</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">No hardware? Verify the signal processing pipeline with the deterministic reference signal: <code>python v1/data/proof/verify.py</code></p>
</blockquote>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📖 Documentation</h2><a id="user-content--documentation" class="anchor" aria-label="Permalink: 📖 Documentation" href="#-documentation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Document</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="docs/user-guide.md">User Guide</a></td>
<td>Step-by-step guide: installation, first run, API usage, hardware setup, training</td>
</tr>
<tr>
<td><a href="docs/build-guide.md">Build Guide</a></td>
<td>Building from source (Rust and Python)</td>
</tr>
<tr>
<td><a href="docs/adr/README.md">Architecture Decisions</a></td>
<td>49 ADRs — why each technical choice was made, organized by domain (hardware, signal processing, ML, platform, infrastructure)</td>
</tr>
<tr>
<td><a href="docs/ddd/README.md">Domain Models</a></td>
<td>7 DDD models (RuvSense, Signal Processing, Training Pipeline, Hardware Platform, Sensing Server, WiFi-Mat, CHCI) — bounded contexts, aggregates, domain events, and ubiquitous language</td>
</tr>
<tr>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-desktop/README.md">Desktop App</a></td>
<td><strong>WIP</strong> — Tauri v2 desktop app for node management, OTA updates, WASM deployment, and mesh visualization</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<hr>
  <a href="https://ruvnet.github.io/RuView/" rel="nofollow">
    <img src="assets/v2-screen.png" alt="WiFi DensePose — Live pose detection with setup guide" width="800" style="max-width: 100%;">
  </a>
  <br>
  <em>Real-time pose skeleton from WiFi CSI signals — no cameras, no wearables</em>
  <br><br>
  <a href="https://ruvnet.github.io/RuView/" rel="nofollow"><strong>▶ Live Observatory Demo</strong></a>
   | 
  <a href="https://ruvnet.github.io/RuView/pose-fusion.html" rel="nofollow"><strong>▶ Dual-Modal Pose Fusion Demo</strong></a>
<blockquote>
<p dir="auto">The <a href="#-quick-start">server</a> is optional for visualization and aggregation — the ESP32 <a href="#esp32-s3-hardware-pipeline">runs independently</a> for presence detection, vital signs, and fall alerts.</p>
<p dir="auto"><strong>Live ESP32 pipeline</strong>: Connect an ESP32-S3 node → run the <a href="#sensing-server">sensing server</a> → open the <a href="https://ruvnet.github.io/RuView/pose-fusion.html" rel="nofollow">pose fusion demo</a> for real-time dual-modal pose estimation (webcam + WiFi CSI). See <a href="docs/adr/ADR-059-live-esp32-csi-pipeline.md">ADR-059</a>.</p>
</blockquote>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🚀 Key Features</h2><a id="user-content--key-features" class="anchor" aria-label="Permalink: 🚀 Key Features" href="#-key-features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Sensing</h3><a id="user-content-sensing" class="anchor" aria-label="Permalink: Sensing" href="#sensing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See people, breathing, and heartbeats through walls — using only WiFi signals already in the room.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th>Feature</th>
<th>What It Means</th>
</tr>
</thead>
<tbody>
<tr>
<td>🔒</td>
<td><strong>Privacy-First</strong></td>
<td>Tracks human pose using only WiFi signals — no cameras, no video, no images stored</td>
</tr>
<tr>
<td>💓</td>
<td><strong>Vital Signs</strong></td>
<td>Detects breathing rate (6-30 breaths/min) and heart rate (40-120 bpm) without any wearable</td>
</tr>
<tr>
<td>👥</td>
<td><strong>Multi-Person</strong></td>
<td>Tracks multiple people simultaneously, each with independent pose and vitals — no hard software limit (physics: ~3-5 per AP with 56 subcarriers, more with multi-AP)</td>
</tr>
<tr>
<td>🧱</td>
<td><strong>Through-Wall</strong></td>
<td>WiFi passes through walls, furniture, and debris — works where cameras cannot</td>
</tr>
<tr>
<td>🚑</td>
<td><strong>Disaster Response</strong></td>
<td>Detects trapped survivors through rubble and classifies injury severity (START triage)</td>
</tr>
<tr>
<td>📡</td>
<td><strong>Multistatic Mesh</strong></td>
<td>4-6 low-cost sensor nodes work together, combining 12+ overlapping signal paths for full 360-degree room coverage with sub-inch accuracy and no person mix-ups (<a href="docs/adr/ADR-029-ruvsense-multistatic-sensing-mode.md">ADR-029</a>)</td>
</tr>
<tr>
<td>🌐</td>
<td><strong>Persistent Field Model</strong></td>
<td>The system learns the RF signature of each room — then subtracts the room to isolate human motion, detect drift over days, predict intent before movement starts, and flag spoofing attempts (<a href="docs/adr/ADR-030-ruvsense-persistent-field-model.md">ADR-030</a>)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Intelligence</h3><a id="user-content-intelligence" class="anchor" aria-label="Permalink: Intelligence" href="#intelligence"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The system learns on its own and gets smarter over time — no hand-tuning, no labeled data required.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th>Feature</th>
<th>What It Means</th>
</tr>
</thead>
<tbody>
<tr>
<td>🧠</td>
<td><strong>Self-Learning</strong></td>
<td>Teaches itself from raw WiFi data — no labeled training sets, no cameras needed to bootstrap (<a href="docs/adr/ADR-024-contrastive-csi-embedding-model.md">ADR-024</a>)</td>
</tr>
<tr>
<td>🎯</td>
<td><strong>AI Signal Processing</strong></td>
<td>Attention networks, graph algorithms, and smart compression replace hand-tuned thresholds — adapts to each room automatically (<a href="https://github.com/ruvnet/ruvector">RuVector</a>)</td>
</tr>
<tr>
<td>🌍</td>
<td><strong>Works Everywhere</strong></td>
<td>Train once, deploy in any room — adversarial domain generalization strips environment bias so models transfer across rooms, buildings, and hardware (<a href="docs/adr/ADR-027-cross-environment-domain-generalization.md">ADR-027</a>)</td>
</tr>
<tr>
<td>👁️</td>
<td><strong>Cross-Viewpoint Fusion</strong></td>
<td>AI combines what each sensor sees from its own angle — fills in blind spots and depth ambiguity that no single viewpoint can resolve on its own (<a href="docs/adr/ADR-031-ruview-sensing-first-rf-mode.md">ADR-031</a>)</td>
</tr>
<tr>
<td>🔮</td>
<td><strong>Signal-Line Protocol</strong></td>
<td>A 6-stage processing pipeline transforms raw WiFi signals into structured body representations — from signal cleanup through graph-based spatial reasoning to final pose output (<a href="docs/adr/ADR-033-crv-signal-line-sensing-integration.md">ADR-033</a>)</td>
</tr>
<tr>
<td>🔒</td>
<td><strong>QUIC Mesh Security</strong></td>
<td>All sensor-to-sensor communication is encrypted end-to-end with tamper detection, replay protection, and seamless reconnection if a node moves or drops offline (<a href="docs/adr/ADR-032-multistatic-mesh-security-hardening.md">ADR-032</a>)</td>
</tr>
<tr>
<td>🎯</td>
<td><strong>Adaptive Classifier</strong></td>
<td>Records labeled CSI sessions, trains a 15-feature logistic regression model in pure Rust, and learns your room's unique signal characteristics — replaces hand-tuned thresholds with data-driven classification (<a href="docs/adr/ADR-048-adaptive-csi-classifier.md">ADR-048</a>)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Performance &amp; Deployment</h3><a id="user-content-performance--deployment" class="anchor" aria-label="Permalink: Performance &amp; Deployment" href="#performance--deployment"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Fast enough for real-time use, small enough for edge devices, simple enough for one-command setup.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th>Feature</th>
<th>What It Means</th>
</tr>
</thead>
<tbody>
<tr>
<td>⚡</td>
<td><strong>Real-Time</strong></td>
<td>Analyzes WiFi signals in under 100 microseconds per frame — fast enough for live monitoring</td>
</tr>
<tr>
<td>🦀</td>
<td><strong>810x Faster</strong></td>
<td>Complete Rust rewrite: 54,000 frames/sec pipeline, multi-arch Docker image, 1,031+ tests</td>
</tr>
<tr>
<td>🐳</td>
<td><strong>One-Command Setup</strong></td>
<td><code>docker pull ruvnet/wifi-densepose:latest</code> — live sensing in 30 seconds, no toolchain needed (amd64 + arm64 / Apple Silicon)</td>
</tr>
<tr>
<td>📡</td>
<td><strong>Fully Local</strong></td>
<td>Runs completely on a $9 ESP32 — no internet connection, no cloud account, no recurring fees. Detects presence, vital signs, and falls on-device with instant response</td>
</tr>
<tr>
<td>📦</td>
<td><strong>Portable Models</strong></td>
<td>Trained models package into a single <code>.rvf</code> file — runs on edge, cloud, or browser (WASM)</td>
</tr>
<tr>
<td>🔭</td>
<td><strong>Observatory Visualization</strong></td>
<td>Cinematic Three.js dashboard with 5 holographic panels — subcarrier manifold, vital signs oracle, presence heatmap, phase constellation, convergence engine — all driven by live or demo CSI data (<a href="docs/adr/ADR-047-psychohistory-observatory-visualization.md">ADR-047</a>)</td>
</tr>
<tr>
<td>📟</td>
<td><strong>AMOLED Display</strong></td>
<td>ESP32-S3 boards with built-in AMOLED screens show real-time presence, vital signs, and room status directly on the sensor — no phone or PC needed (<a href="docs/adr/ADR-045-amoled-display-support.md">ADR-045</a>)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🔬 How It Works</h2><a id="user-content--how-it-works" class="anchor" aria-label="Permalink: 🔬 How It Works" href="#-how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">WiFi routers flood every room with radio waves. When a person moves — or even breathes — those waves scatter differently. WiFi DensePose reads that scattering pattern and reconstructs what happened:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="WiFi Router → radio waves pass through room → hit human body → scatter
    ↓
ESP32 mesh (4-6 nodes) captures CSI on channels 1/6/11 via TDM protocol
    ↓
Multi-Band Fusion: 3 channels × 56 subcarriers = 168 virtual subcarriers per link
    ↓
Multistatic Fusion: N×(N-1) links → attention-weighted cross-viewpoint embedding
    ↓
Coherence Gate: accept/reject measurements → stable for days without tuning
    ↓
Signal Processing: Hampel, SpotFi, Fresnel, BVP, spectrogram → clean features
    ↓
AI Backbone (RuVector): attention, graph algorithms, compression, field model
    ↓
Signal-Line Protocol (CRV): 6-stage gestalt → sensory → topology → coherence → search → model
    ↓
Neural Network: processed signals → 17 body keypoints + vital signs + room model
    ↓
Output: real-time pose, breathing, heart rate, room fingerprint, drift alerts"><pre class="notranslate"><code>WiFi Router → radio waves pass through room → hit human body → scatter
    ↓
ESP32 mesh (4-6 nodes) captures CSI on channels 1/6/11 via TDM protocol
    ↓
Multi-Band Fusion: 3 channels × 56 subcarriers = 168 virtual subcarriers per link
    ↓
Multistatic Fusion: N×(N-1) links → attention-weighted cross-viewpoint embedding
    ↓
Coherence Gate: accept/reject measurements → stable for days without tuning
    ↓
Signal Processing: Hampel, SpotFi, Fresnel, BVP, spectrogram → clean features
    ↓
AI Backbone (RuVector): attention, graph algorithms, compression, field model
    ↓
Signal-Line Protocol (CRV): 6-stage gestalt → sensory → topology → coherence → search → model
    ↓
Neural Network: processed signals → 17 body keypoints + vital signs + room model
    ↓
Output: real-time pose, breathing, heart rate, room fingerprint, drift alerts
</code></pre></div>
<p dir="auto">No training cameras required — the <a href="docs/adr/ADR-024-contrastive-csi-embedding-model.md">Self-Learning system (ADR-024)</a> bootstraps from raw WiFi data alone. <a href="docs/adr/ADR-027-cross-environment-domain-generalization.md">MERIDIAN (ADR-027)</a> ensures the model works in any room, not just the one it trained in.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🏢 Use Cases &amp; Applications</h2><a id="user-content--use-cases--applications" class="anchor" aria-label="Permalink: 🏢 Use Cases &amp; Applications" href="#-use-cases--applications"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">WiFi sensing works anywhere WiFi exists. No new hardware in most cases — just software on existing access points or a $8 ESP32 add-on. Because there are no cameras, deployments avoid privacy regulations (GDPR video, HIPAA imaging) by design.</p>
<p dir="auto"><strong>Scaling:</strong> Each AP distinguishes ~3-5 people (56 subcarriers). Multi-AP multiplies linearly — a 4-AP retail mesh covers ~15-20 occupants. No hard software limit; the practical ceiling is signal physics.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th>Why WiFi sensing wins</th>
<th>Traditional alternative</th>
</tr>
</thead>
<tbody>
<tr>
<td>🔒</td>
<td><strong>No video, no GDPR/HIPAA imaging rules</strong></td>
<td>Cameras require consent, signage, data retention policies</td>
</tr>
<tr>
<td>🧱</td>
<td><strong>Works through walls, shelving, debris</strong></td>
<td>Cameras need line-of-sight per room</td>
</tr>
<tr>
<td>🌙</td>
<td><strong>Works in total darkness</strong></td>
<td>Cameras need IR or visible light</td>
</tr>
<tr>
<td>💰</td>
<td><strong>$0-$8 per zone</strong> (existing WiFi or ESP32)</td>
<td>Camera systems: $200-$2,000 per zone</td>
</tr>
<tr>
<td>🔌</td>
<td><strong>WiFi already deployed everywhere</strong></td>
<td>PIR/radar sensors require new wiring per room</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<details>
<summary><strong>🏥 Everyday</strong> — Healthcare, retail, office, hospitality (commodity WiFi)</summary>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Use Case</th>
<th>What It Does</th>
<th>Hardware</th>
<th>Key Metric</th>
<th>Edge Module</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Elderly care / assisted living</strong></td>
<td>Fall detection, nighttime activity monitoring, breathing rate during sleep — no wearable compliance needed</td>
<td>1 ESP32-S3 per room ($8)</td>
<td>Fall alert &lt;2s</td>
<td><a href="docs/edge-modules/medical.md">Sleep Apnea</a>, <a href="docs/edge-modules/medical.md">Gait Analysis</a></td>
</tr>
<tr>
<td><strong>Hospital patient monitoring</strong></td>
<td>Continuous breathing + heart rate for non-critical beds without wired sensors; nurse alert on anomaly</td>
<td>1-2 APs per ward</td>
<td>Breathing: 6-30 BPM</td>
<td><a href="docs/edge-modules/medical.md">Respiratory Distress</a>, <a href="docs/edge-modules/medical.md">Cardiac Arrhythmia</a></td>
</tr>
<tr>
<td><strong>Emergency room triage</strong></td>
<td>Automated occupancy count + wait-time estimation; detect patient distress (abnormal breathing) in waiting areas</td>
<td>Existing hospital WiFi</td>
<td>Occupancy accuracy &gt;95%</td>
<td><a href="docs/edge-modules/retail.md">Queue Length</a>, <a href="docs/edge-modules/security.md">Panic Motion</a></td>
</tr>
<tr>
<td><strong>Retail occupancy &amp; flow</strong></td>
<td>Real-time foot traffic, dwell time by zone, queue length — no cameras, no opt-in, GDPR-friendly</td>
<td>Existing store WiFi + 1 ESP32</td>
<td>Dwell resolution ~1m</td>
<td><a href="docs/edge-modules/retail.md">Customer Flow</a>, <a href="docs/edge-modules/retail.md">Dwell Heatmap</a></td>
</tr>
<tr>
<td><strong>Office space utilization</strong></td>
<td>Which desks/rooms are actually occupied, meeting room no-shows, HVAC optimization based on real presence</td>
<td>Existing enterprise WiFi</td>
<td>Presence latency &lt;1s</td>
<td><a href="docs/edge-modules/building.md">Meeting Room</a>, <a href="docs/edge-modules/building.md">HVAC Presence</a></td>
</tr>
<tr>
<td><strong>Hotel &amp; hospitality</strong></td>
<td>Room occupancy without door sensors, minibar/bathroom usage patterns, energy savings on empty rooms</td>
<td>Existing hotel WiFi</td>
<td>15-30% HVAC savings</td>
<td><a href="docs/edge-modules/building.md">Energy Audit</a>, <a href="docs/edge-modules/building.md">Lighting Zones</a></td>
</tr>
<tr>
<td><strong>Restaurants &amp; food service</strong></td>
<td>Table turnover tracking, kitchen staff presence, restroom occupancy displays — no cameras in dining areas</td>
<td>Existing WiFi</td>
<td>Queue wait ±30s</td>
<td><a href="docs/edge-modules/retail.md">Table Turnover</a>, <a href="docs/edge-modules/retail.md">Queue Length</a></td>
</tr>
<tr>
<td><strong>Parking garages</strong></td>
<td>Pedestrian presence in stairwells and elevators where cameras have blind spots; security alert if someone lingers</td>
<td>Existing WiFi</td>
<td>Through-concrete walls</td>
<td><a href="docs/edge-modules/security.md">Loitering</a>, <a href="docs/edge-modules/building.md">Elevator Count</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>🏟️ Specialized</strong> — Events, fitness, education, civic (CSI-capable hardware)</summary>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Use Case</th>
<th>What It Does</th>
<th>Hardware</th>
<th>Key Metric</th>
<th>Edge Module</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Smart home automation</strong></td>
<td>Room-level presence triggers (lights, HVAC, music) that work through walls — no dead zones, no motion-sensor timeouts</td>
<td>2-3 ESP32-S3 nodes ($24)</td>
<td>Through-wall range ~5m</td>
<td><a href="docs/edge-modules/building.md">HVAC Presence</a>, <a href="docs/edge-modules/building.md">Lighting Zones</a></td>
</tr>
<tr>
<td><strong>Fitness &amp; sports</strong></td>
<td>Rep counting, posture correction, breathing cadence during exercise — no wearable, no camera in locker rooms</td>
<td>3+ ESP32-S3 mesh</td>
<td>Pose: 17 keypoints</td>
<td><a href="docs/edge-modules/exotic.md">Breathing Sync</a>, <a href="docs/edge-modules/medical.md">Gait Analysis</a></td>
</tr>
<tr>
<td><strong>Childcare &amp; schools</strong></td>
<td>Naptime breathing monitoring, playground headcount, restricted-area alerts — privacy-safe for minors</td>
<td>2-4 ESP32-S3 per zone</td>
<td>Breathing: ±1 BPM</td>
<td><a href="docs/edge-modules/medical.md">Sleep Apnea</a>, <a href="docs/edge-modules/security.md">Perimeter Breach</a></td>
</tr>
<tr>
<td><strong>Event venues &amp; concerts</strong></td>
<td>Crowd density mapping, crush-risk detection via breathing compression, emergency evacuation flow tracking</td>
<td>Multi-AP mesh (4-8 APs)</td>
<td>Density per m²</td>
<td><a href="docs/edge-modules/retail.md">Customer Flow</a>, <a href="docs/edge-modules/security.md">Panic Motion</a></td>
</tr>
<tr>
<td><strong>Stadiums &amp; arenas</strong></td>
<td>Section-level occupancy for dynamic pricing, concession staffing, emergency egress flow modeling</td>
<td>Enterprise AP grid</td>
<td>15-20 per AP mesh</td>
<td><a href="docs/edge-modules/retail.md">Dwell Heatmap</a>, <a href="docs/edge-modules/retail.md">Queue Length</a></td>
</tr>
<tr>
<td><strong>Houses of worship</strong></td>
<td>Attendance counting without facial recognition — privacy-sensitive congregations, multi-room campus tracking</td>
<td>Existing WiFi</td>
<td>Zone-level accuracy</td>
<td><a href="docs/edge-modules/building.md">Elevator Count</a>, <a href="docs/edge-modules/building.md">Energy Audit</a></td>
</tr>
<tr>
<td><strong>Warehouse &amp; logistics</strong></td>
<td>Worker safety zones, forklift proximity alerts, occupancy in hazardous areas — works through shelving and pallets</td>
<td>Industrial AP mesh</td>
<td>Alert latency &lt;500ms</td>
<td><a href="docs/edge-modules/industrial.md">Forklift Proximity</a>, <a href="docs/edge-modules/industrial.md">Confined Space</a></td>
</tr>
<tr>
<td><strong>Civic infrastructure</strong></td>
<td>Public restroom occupancy (no cameras possible), subway platform crowding, shelter headcount during emergencies</td>
<td>Municipal WiFi + ESP32</td>
<td>Real-time headcount</td>
<td><a href="docs/edge-modules/retail.md">Customer Flow</a>, <a href="docs/edge-modules/security.md">Loitering</a></td>
</tr>
<tr>
<td><strong>Museums &amp; galleries</strong></td>
<td>Visitor flow heatmaps, exhibit dwell time, crowd bottleneck alerts — no cameras near artwork (flash/theft risk)</td>
<td>Existing WiFi</td>
<td>Zone dwell ±5s</td>
<td><a href="docs/edge-modules/retail.md">Dwell Heatmap</a>, <a href="docs/edge-modules/retail.md">Shelf Engagement</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>🤖 Robotics &amp; Industrial</strong> — Autonomous systems, manufacturing, android spatial awareness</summary>
<p dir="auto">WiFi sensing gives robots and autonomous systems a spatial awareness layer that works where LIDAR and cameras fail — through dust, smoke, fog, and around corners. The CSI signal field acts as a "sixth sense" for detecting humans in the environment without requiring line-of-sight.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Use Case</th>
<th>What It Does</th>
<th>Hardware</th>
<th>Key Metric</th>
<th>Edge Module</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Cobot safety zones</strong></td>
<td>Detect human presence near collaborative robots — auto-slow or stop before contact, even behind obstructions</td>
<td>2-3 ESP32-S3 per cell</td>
<td>Presence latency &lt;100ms</td>
<td><a href="docs/edge-modules/industrial.md">Forklift Proximity</a>, <a href="docs/edge-modules/security.md">Perimeter Breach</a></td>
</tr>
<tr>
<td><strong>Warehouse AMR navigation</strong></td>
<td>Autonomous mobile robots sense humans around blind corners, through shelving racks — no LIDAR occlusion</td>
<td>ESP32 mesh along aisles</td>
<td>Through-shelf detection</td>
<td><a href="docs/edge-modules/industrial.md">Forklift Proximity</a>, <a href="docs/edge-modules/security.md">Loitering</a></td>
</tr>
<tr>
<td><strong>Android / humanoid spatial awareness</strong></td>
<td>Ambient human pose sensing for social robots — detect gestures, approach direction, and personal space without cameras always on</td>
<td>Onboard ESP32-S3 module</td>
<td>17-keypoint pose</td>
<td><a href="docs/edge-modules/exotic.md">Gesture Language</a>, <a href="docs/edge-modules/exotic.md">Emotion Detection</a></td>
</tr>
<tr>
<td><strong>Manufacturing line monitoring</strong></td>
<td>Worker presence at each station, ergonomic posture alerts, headcount for shift compliance — works through equipment</td>
<td>Industrial AP per zone</td>
<td>Pose + breathing</td>
<td><a href="docs/edge-modules/industrial.md">Confined Space</a>, <a href="docs/edge-modules/medical.md">Gait Analysis</a></td>
</tr>
<tr>
<td><strong>Construction site safety</strong></td>
<td>Exclusion zone enforcement around heavy machinery, fall detection from scaffolding, personnel headcount</td>
<td>Ruggedized ESP32 mesh</td>
<td>Alert &lt;2s, through-dust</td>
<td><a href="docs/edge-modules/security.md">Panic Motion</a>, <a href="docs/edge-modules/industrial.md">Structural Vibration</a></td>
</tr>
<tr>
<td><strong>Agricultural robotics</strong></td>
<td>Detect farm workers near autonomous harvesters in dusty/foggy field conditions where cameras are unreliable</td>
<td>Weatherproof ESP32 nodes</td>
<td>Range ~10m open field</td>
<td><a href="docs/edge-modules/industrial.md">Forklift Proximity</a>, <a href="docs/edge-modules/exotic.md">Rain Detection</a></td>
</tr>
<tr>
<td><strong>Drone landing zones</strong></td>
<td>Verify landing area is clear of humans — WiFi sensing works in rain, dust, and low light where downward cameras fail</td>
<td>Ground ESP32 nodes</td>
<td>Presence: &gt;95% accuracy</td>
<td><a href="docs/edge-modules/security.md">Perimeter Breach</a>, <a href="docs/edge-modules/security.md">Tailgating</a></td>
</tr>
<tr>
<td><strong>Clean room monitoring</strong></td>
<td>Personnel tracking without cameras (particle contamination risk from camera fans) — gown compliance via pose</td>
<td>Existing cleanroom WiFi</td>
<td>No particulate emission</td>
<td><a href="docs/edge-modules/industrial.md">Clean Room</a>, <a href="docs/edge-modules/industrial.md">Livestock Monitor</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>🔥 Extreme</strong> — Through-wall, disaster, defense, underground</summary>
<p dir="auto">These scenarios exploit WiFi's ability to penetrate solid materials — concrete, rubble, earth — where no optical or infrared sensor can reach. The WiFi-Mat disaster module (ADR-001) is specifically designed for this tier.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Use Case</th>
<th>What It Does</th>
<th>Hardware</th>
<th>Key Metric</th>
<th>Edge Module</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Search &amp; rescue (WiFi-Mat)</strong></td>
<td>Detect survivors through rubble/debris via breathing signature, START triage color classification, 3D localization</td>
<td>Portable ESP32 mesh + laptop</td>
<td>Through 30cm concrete</td>
<td><a href="docs/edge-modules/medical.md">Respiratory Distress</a>, <a href="docs/edge-modules/medical.md">Seizure Detection</a></td>
</tr>
<tr>
<td><strong>Firefighting</strong></td>
<td>Locate occupants through smoke and walls before entry; breathing detection confirms life signs remotely</td>
<td>Portable mesh on truck</td>
<td>Works in zero visibility</td>
<td><a href="docs/edge-modules/medical.md">Sleep Apnea</a>, <a href="docs/edge-modules/security.md">Panic Motion</a></td>
</tr>
<tr>
<td><strong>Prison &amp; secure facilities</strong></td>
<td>Cell occupancy verification, distress detection (abnormal vitals), perimeter sensing — no camera blind spots</td>
<td>Dedicated AP infrastructure</td>
<td>24/7 vital signs</td>
<td><a href="docs/edge-modules/medical.md">Cardiac Arrhythmia</a>, <a href="docs/edge-modules/security.md">Loitering</a></td>
</tr>
<tr>
<td><strong>Military / tactical</strong></td>
<td>Through-wall personnel detection, room clearing confirmation, hostage vital signs at standoff distance</td>
<td>Directional WiFi + custom FW</td>
<td>Range: 5m through wall</td>
<td><a href="docs/edge-modules/security.md">Perimeter Breach</a>, <a href="docs/edge-modules/security.md">Weapon Detection</a></td>
</tr>
<tr>
<td><strong>Border &amp; perimeter security</strong></td>
<td>Detect human presence in tunnels, behind fences, in vehicles — passive sensing, no active illumination to reveal position</td>
<td>Concealed ESP32 mesh</td>
<td>Passive / covert</td>
<td><a href="docs/edge-modules/security.md">Perimeter Breach</a>, <a href="docs/edge-modules/security.md">Tailgating</a></td>
</tr>
<tr>
<td><strong>Mining &amp; underground</strong></td>
<td>Worker presence in tunnels where GPS/cameras fail, breathing detection after collapse, headcount at safety points</td>
<td>Ruggedized ESP32 mesh</td>
<td>Through rock/earth</td>
<td><a href="docs/edge-modules/industrial.md">Confined Space</a>, <a href="docs/edge-modules/medical.md">Respiratory Distress</a></td>
</tr>
<tr>
<td><strong>Maritime &amp; naval</strong></td>
<td>Below-deck personnel tracking through steel bulkheads (limited range, requires tuning), man-overboard detection</td>
<td>Ship WiFi + ESP32</td>
<td>Through 1-2 bulkheads</td>
<td><a href="docs/edge-modules/industrial.md">Structural Vibration</a>, <a href="docs/edge-modules/security.md">Panic Motion</a></td>
</tr>
<tr>
<td><strong>Wildlife research</strong></td>
<td>Non-invasive animal activity monitoring in enclosures or dens — no light pollution, no visual disturbance</td>
<td>Weatherproof ESP32 nodes</td>
<td>Zero light emission</td>
<td><a href="docs/edge-modules/industrial.md">Livestock Monitor</a>, <a href="docs/edge-modules/exotic.md">Dream Stage</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Edge Intelligence (<a href="docs/adr/ADR-041-wasm-module-collection.md">ADR-041</a>)</h3><a id="user-content-edge-intelligence-adr-041" class="anchor" aria-label="Permalink: Edge Intelligence (ADR-041)" href="#edge-intelligence-adr-041"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Small programs that run directly on the ESP32 sensor — no internet needed, no cloud fees, instant response. Each module is a tiny WASM file (5-30 KB) that you upload to the device over-the-air. It reads WiFi signal data and makes decisions locally in under 10 ms. <a href="docs/adr/ADR-041-wasm-module-collection.md">ADR-041</a> defines 60 modules across 13 categories — all 60 are implemented with 609 tests passing.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th></th>
<th>Category</th>
<th>Examples</th>
</tr>
</thead>
<tbody>
<tr>
<td>🏥</td>
<td><a href="docs/edge-modules/medical.md"><strong>Medical &amp; Health</strong></a></td>
<td>Sleep apnea detection, cardiac arrhythmia, gait analysis, seizure detection</td>
</tr>
<tr>
<td>🔐</td>
<td><a href="docs/edge-modules/security.md"><strong>Security &amp; Safety</strong></a></td>
<td>Intrusion detection, perimeter breach, loitering, panic motion</td>
</tr>
<tr>
<td>🏢</td>
<td><a href="docs/edge-modules/building.md"><strong>Smart Building</strong></a></td>
<td>Zone occupancy, HVAC control, elevator counting, meeting room tracking</td>
</tr>
<tr>
<td>🛒</td>
<td><a href="docs/edge-modules/retail.md"><strong>Retail &amp; Hospitality</strong></a></td>
<td>Queue length, dwell heatmaps, customer flow, table turnover</td>
</tr>
<tr>
<td>🏭</td>
<td><a href="docs/edge-modules/industrial.md"><strong>Industrial</strong></a></td>
<td>Forklift proximity, confined space monitoring, structural vibration</td>
</tr>
<tr>
<td>🔮</td>
<td><a href="docs/edge-modules/exotic.md"><strong>Exotic &amp; Research</strong></a></td>
<td>Sleep staging, emotion detection, sign language, breathing sync</td>
</tr>
<tr>
<td>📡</td>
<td><a href="docs/edge-modules/signal-intelligence.md"><strong>Signal Intelligence</strong></a></td>
<td>Cleans and sharpens raw WiFi signals — focuses on important regions, filters noise, fills in missing data, and tracks which person is which</td>
</tr>
<tr>
<td>🧠</td>
<td><a href="docs/edge-modules/adaptive-learning.md"><strong>Adaptive Learning</strong></a></td>
<td>The sensor learns new gestures and patterns on its own over time — no cloud needed, remembers what it learned even after updates</td>
</tr>
<tr>
<td>🗺️</td>
<td><a href="docs/edge-modules/spatial-temporal.md"><strong>Spatial Reasoning</strong></a></td>
<td>Figures out where people are in a room, which zones matter most, and tracks movement across areas using graph-based spatial logic</td>
</tr>
<tr>
<td>⏱️</td>
<td><a href="docs/edge-modules/spatial-temporal.md"><strong>Temporal Analysis</strong></a></td>
<td>Learns daily routines, detects when patterns break (someone didn't get up), and verifies safety rules are being followed over time</td>
</tr>
<tr>
<td>🛡️</td>
<td><a href="docs/edge-modules/ai-security.md"><strong>AI Security</strong></a></td>
<td>Detects signal replay attacks, WiFi jamming, injection attempts, and flags abnormal behavior that could indicate tampering</td>
</tr>
<tr>
<td>⚛️</td>
<td><a href="docs/edge-modules/autonomous.md"><strong>Quantum-Inspired</strong></a></td>
<td>Uses quantum-inspired math to map room-wide signal coherence and search for optimal sensor configurations</td>
</tr>
<tr>
<td>🤖</td>
<td><a href="docs/edge-modules/autonomous.md"><strong>Autonomous &amp; Exotic</strong></a></td>
<td>Self-managing sensor mesh — auto-heals dropped nodes, plans its own actions, and explores experimental signal representations</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">All implemented modules are <code>no_std</code> Rust, share a <a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/vendor_common.rs">common utility library</a>, and talk to the host through a 12-function API. Full documentation: <a href="docs/edge-modules/README.md"><strong>Edge Modules Guide</strong></a>. See the <a href="#edge-module-list">complete implemented module list</a> below.</p>
<details id="user-content-edge-module-list">
<summary><strong>🧩 Edge Intelligence — <a href="docs/edge-modules/README.md">All 65 Modules Implemented</a></strong> (ADR-041 complete)</summary>
<p dir="auto">All 60 modules are implemented, tested (609 tests passing), and ready to deploy. They compile to <code>wasm32-unknown-unknown</code>, run on ESP32-S3 via WASM3, and share a <a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/vendor_common.rs">common utility library</a>. Source: <a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/"><code>crates/wifi-densepose-wasm-edge/src/</code></a></p>
<p dir="auto"><strong>Core modules</strong> (ADR-040 flagship + early implementations):</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gesture Classifier</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/gesture.rs"><code>gesture.rs</code></a></td>
<td>DTW template matching for hand gestures</td>
</tr>
<tr>
<td>Coherence Filter</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/coherence.rs"><code>coherence.rs</code></a></td>
<td>Phase coherence gating for signal quality</td>
</tr>
<tr>
<td>Adversarial Detector</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/adversarial.rs"><code>adversarial.rs</code></a></td>
<td>Detects physically impossible signal patterns</td>
</tr>
<tr>
<td>Intrusion Detector</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/intrusion.rs"><code>intrusion.rs</code></a></td>
<td>Human vs non-human motion classification</td>
</tr>
<tr>
<td>Occupancy Counter</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/occupancy.rs"><code>occupancy.rs</code></a></td>
<td>Zone-level person counting</td>
</tr>
<tr>
<td>Vital Trend</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/vital_trend.rs"><code>vital_trend.rs</code></a></td>
<td>Long-term breathing and heart rate trending</td>
</tr>
<tr>
<td>RVF Parser</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/rvf.rs"><code>rvf.rs</code></a></td>
<td>RVF container format parsing</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Vendor-integrated modules</strong> (24 modules, ADR-041 Category 7):</p>
<p dir="auto"><strong>📡 Signal Intelligence</strong> — Real-time CSI analysis and feature extraction</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Flash Attention</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sig_flash_attention.rs"><code>sig_flash_attention.rs</code></a></td>
<td>Tiled attention over 8 subcarrier groups — finds spatial focus regions and entropy</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Coherence Gate</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sig_coherence_gate.rs"><code>sig_coherence_gate.rs</code></a></td>
<td>Z-score phasor gating with hysteresis: Accept / PredictOnly / Reject / Recalibrate</td>
<td>L (&lt;2ms)</td>
</tr>
<tr>
<td>Temporal Compress</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sig_temporal_compress.rs"><code>sig_temporal_compress.rs</code></a></td>
<td>3-tier adaptive quantization (8-bit hot / 5-bit warm / 3-bit cold)</td>
<td>L (&lt;2ms)</td>
</tr>
<tr>
<td>Sparse Recovery</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sig_sparse_recovery.rs"><code>sig_sparse_recovery.rs</code></a></td>
<td>ISTA L1 reconstruction for dropped subcarriers</td>
<td>H (&lt;10ms)</td>
</tr>
<tr>
<td>Person Match</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sig_mincut_person_match.rs"><code>sig_mincut_person_match.rs</code></a></td>
<td>Hungarian-lite bipartite assignment for multi-person tracking</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Optimal Transport</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sig_optimal_transport.rs"><code>sig_optimal_transport.rs</code></a></td>
<td>Sliced Wasserstein-1 distance with 4 projections</td>
<td>L (&lt;2ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🧠 Adaptive Learning</strong> — On-device learning without cloud connectivity</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>DTW Gesture Learn</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/lrn_dtw_gesture_learn.rs"><code>lrn_dtw_gesture_learn.rs</code></a></td>
<td>User-teachable gesture recognition — 3-rehearsal protocol, 16 templates</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Anomaly Attractor</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/lrn_anomaly_attractor.rs"><code>lrn_anomaly_attractor.rs</code></a></td>
<td>4D dynamical system attractor classification with Lyapunov exponents</td>
<td>H (&lt;10ms)</td>
</tr>
<tr>
<td>Meta Adapt</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/lrn_meta_adapt.rs"><code>lrn_meta_adapt.rs</code></a></td>
<td>Hill-climbing self-optimization with safety rollback</td>
<td>L (&lt;2ms)</td>
</tr>
<tr>
<td>EWC Lifelong</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/lrn_ewc_lifelong.rs"><code>lrn_ewc_lifelong.rs</code></a></td>
<td>Elastic Weight Consolidation — remembers past tasks while learning new ones</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🗺️ Spatial Reasoning</strong> — Location, proximity, and influence mapping</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>PageRank Influence</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/spt_pagerank_influence.rs"><code>spt_pagerank_influence.rs</code></a></td>
<td>4x4 cross-correlation graph with power iteration PageRank</td>
<td>L (&lt;2ms)</td>
</tr>
<tr>
<td>Micro HNSW</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/spt_micro_hnsw.rs"><code>spt_micro_hnsw.rs</code></a></td>
<td>64-vector navigable small-world graph for nearest-neighbor search</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Spiking Tracker</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/spt_spiking_tracker.rs"><code>spt_spiking_tracker.rs</code></a></td>
<td>32 LIF neurons + 4 output zone neurons with STDP learning</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>⏱️ Temporal Analysis</strong> — Activity patterns, logic verification, autonomous planning</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pattern Sequence</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/tmp_pattern_sequence.rs"><code>tmp_pattern_sequence.rs</code></a></td>
<td>Activity routine detection and deviation alerts</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Temporal Logic Guard</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/tmp_temporal_logic_guard.rs"><code>tmp_temporal_logic_guard.rs</code></a></td>
<td>LTL formula verification on CSI event streams</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>GOAP Autonomy</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/tmp_goap_autonomy.rs"><code>tmp_goap_autonomy.rs</code></a></td>
<td>Goal-Oriented Action Planning for autonomous module management</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🛡️ AI Security</strong> — Tamper detection and behavioral anomaly profiling</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Prompt Shield</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ais_prompt_shield.rs"><code>ais_prompt_shield.rs</code></a></td>
<td>FNV-1a replay detection, injection detection (10x amplitude), jamming (SNR)</td>
<td>L (&lt;2ms)</td>
</tr>
<tr>
<td>Behavioral Profiler</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ais_behavioral_profiler.rs"><code>ais_behavioral_profiler.rs</code></a></td>
<td>6D behavioral profile with Mahalanobis anomaly scoring</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>⚛️ Quantum-Inspired</strong> — Quantum computing metaphors applied to CSI analysis</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Quantum Coherence</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/qnt_quantum_coherence.rs"><code>qnt_quantum_coherence.rs</code></a></td>
<td>Bloch sphere mapping, Von Neumann entropy, decoherence detection</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Interference Search</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/qnt_interference_search.rs"><code>qnt_interference_search.rs</code></a></td>
<td>16 room-state hypotheses with Grover-inspired oracle + diffusion</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🤖 Autonomous Systems</strong> — Self-governing and self-healing behaviors</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Psycho-Symbolic</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/aut_psycho_symbolic.rs"><code>aut_psycho_symbolic.rs</code></a></td>
<td>16-rule forward-chaining knowledge base with contradiction detection</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Self-Healing Mesh</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/aut_self_healing_mesh.rs"><code>aut_self_healing_mesh.rs</code></a></td>
<td>8-node mesh with health tracking, degradation/recovery, coverage healing</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🔮 Exotic (Vendor)</strong> — Novel mathematical models for CSI interpretation</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Time Crystal</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_time_crystal.rs"><code>exo_time_crystal.rs</code></a></td>
<td>Autocorrelation subharmonic detection in 256-frame history</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Hyperbolic Space</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_hyperbolic_space.rs"><code>exo_hyperbolic_space.rs</code></a></td>
<td>Poincare ball embedding with 32 reference locations, hyperbolic distance</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🏥 Medical &amp; Health</strong> (Category 1) — Contactless health monitoring</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sleep Apnea</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/med_sleep_apnea.rs"><code>med_sleep_apnea.rs</code></a></td>
<td>Detects breathing pauses during sleep</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Cardiac Arrhythmia</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/med_cardiac_arrhythmia.rs"><code>med_cardiac_arrhythmia.rs</code></a></td>
<td>Monitors heart rate for irregular rhythms</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Respiratory Distress</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/med_respiratory_distress.rs"><code>med_respiratory_distress.rs</code></a></td>
<td>Alerts on abnormal breathing patterns</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Gait Analysis</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/med_gait_analysis.rs"><code>med_gait_analysis.rs</code></a></td>
<td>Tracks walking patterns and detects changes</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Seizure Detection</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/med_seizure_detect.rs"><code>med_seizure_detect.rs</code></a></td>
<td>6-state machine for tonic-clonic seizure recognition</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🔐 Security &amp; Safety</strong> (Category 2) — Perimeter and threat detection</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Perimeter Breach</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sec_perimeter_breach.rs"><code>sec_perimeter_breach.rs</code></a></td>
<td>Detects boundary crossings with approach/departure</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Weapon Detection</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sec_weapon_detect.rs"><code>sec_weapon_detect.rs</code></a></td>
<td>Metal anomaly detection via CSI amplitude shifts</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Tailgating</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sec_tailgating.rs"><code>sec_tailgating.rs</code></a></td>
<td>Detects unauthorized follow-through at access points</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Loitering</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sec_loitering.rs"><code>sec_loitering.rs</code></a></td>
<td>Alerts when someone lingers too long in a zone</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Panic Motion</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/sec_panic_motion.rs"><code>sec_panic_motion.rs</code></a></td>
<td>Detects fleeing, struggling, or panic movement</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🏢 Smart Building</strong> (Category 3) — Automation and energy efficiency</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>HVAC Presence</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/bld_hvac_presence.rs"><code>bld_hvac_presence.rs</code></a></td>
<td>Occupancy-driven HVAC control with departure countdown</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Lighting Zones</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/bld_lighting_zones.rs"><code>bld_lighting_zones.rs</code></a></td>
<td>Auto-dim/off lighting based on zone activity</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Elevator Count</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/bld_elevator_count.rs"><code>bld_elevator_count.rs</code></a></td>
<td>Counts people entering/leaving with overload warning</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Meeting Room</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/bld_meeting_room.rs"><code>bld_meeting_room.rs</code></a></td>
<td>Tracks meeting lifecycle: start, headcount, end, availability</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Energy Audit</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/bld_energy_audit.rs"><code>bld_energy_audit.rs</code></a></td>
<td>Tracks after-hours usage and room utilization rates</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🛒 Retail &amp; Hospitality</strong> (Category 4) — Customer insights without cameras</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Queue Length</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ret_queue_length.rs"><code>ret_queue_length.rs</code></a></td>
<td>Estimates queue size and wait times</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Dwell Heatmap</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ret_dwell_heatmap.rs"><code>ret_dwell_heatmap.rs</code></a></td>
<td>Shows where people spend time (hot/cold zones)</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Customer Flow</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ret_customer_flow.rs"><code>ret_customer_flow.rs</code></a></td>
<td>Counts ins/outs and tracks net occupancy</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Table Turnover</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ret_table_turnover.rs"><code>ret_table_turnover.rs</code></a></td>
<td>Restaurant table lifecycle: seated, dining, vacated</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Shelf Engagement</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ret_shelf_engagement.rs"><code>ret_shelf_engagement.rs</code></a></td>
<td>Detects browsing, considering, and reaching for products</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🏭 Industrial &amp; Specialized</strong> (Category 5) — Safety and compliance</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Forklift Proximity</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ind_forklift_proximity.rs"><code>ind_forklift_proximity.rs</code></a></td>
<td>Warns when people get too close to vehicles</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Confined Space</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ind_confined_space.rs"><code>ind_confined_space.rs</code></a></td>
<td>OSHA-compliant worker monitoring with extraction alerts</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Clean Room</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ind_clean_room.rs"><code>ind_clean_room.rs</code></a></td>
<td>Occupancy limits and turbulent motion detection</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Livestock Monitor</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ind_livestock_monitor.rs"><code>ind_livestock_monitor.rs</code></a></td>
<td>Animal presence, stillness, and escape alerts</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Structural Vibration</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/ind_structural_vibration.rs"><code>ind_structural_vibration.rs</code></a></td>
<td>Seismic events, mechanical resonance, structural drift</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>🔮 Exotic &amp; Research</strong> (Category 6) — Experimental sensing applications</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Module</th>
<th>File</th>
<th>What It Does</th>
<th>Budget</th>
</tr>
</thead>
<tbody>
<tr>
<td>Dream Stage</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_dream_stage.rs"><code>exo_dream_stage.rs</code></a></td>
<td>Contactless sleep stage classification (wake/light/deep/REM)</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Emotion Detection</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_emotion_detect.rs"><code>exo_emotion_detect.rs</code></a></td>
<td>Arousal, stress, and calm detection from micro-movements</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Gesture Language</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_gesture_language.rs"><code>exo_gesture_language.rs</code></a></td>
<td>Sign language letter recognition via WiFi</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Music Conductor</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_music_conductor.rs"><code>exo_music_conductor.rs</code></a></td>
<td>Tempo and dynamic tracking from conducting gestures</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Plant Growth</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_plant_growth.rs"><code>exo_plant_growth.rs</code></a></td>
<td>Monitors plant growth, circadian rhythms, wilt detection</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Ghost Hunter</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_ghost_hunter.rs"><code>exo_ghost_hunter.rs</code></a></td>
<td>Environmental anomaly classification (draft/insect/wind/unknown)</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Rain Detection</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_rain_detect.rs"><code>exo_rain_detect.rs</code></a></td>
<td>Detects rain onset, intensity, and cessation via signal scatter</td>
<td>S (&lt;5ms)</td>
</tr>
<tr>
<td>Breathing Sync</td>
<td><a href="rust-port/wifi-densepose-rs/crates/wifi-densepose-wasm-edge/src/exo_breathing_sync.rs"><code>exo_breathing_sync.rs</code></a></td>
<td>Detects synchronized breathing between multiple people</td>
<td>S (&lt;5ms)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<hr>
<details>
<summary><strong>🧠 Self-Learning WiFi AI (ADR-024)</strong> — Adaptive recognition, self-optimization, and intelligent anomaly detection</summary>
<p dir="auto">Every WiFi signal that passes through a room creates a unique fingerprint of that space. WiFi-DensePose already reads these fingerprints to track people, but until now it threw away the internal "understanding" after each reading. The Self-Learning WiFi AI captures and preserves that understanding as compact, reusable vectors — and continuously optimizes itself for each new environment.</p>
<p dir="auto"><strong>What it does in plain terms:</strong></p>
<ul dir="auto">
<li>Turns any WiFi signal into a 128-number "fingerprint" that uniquely describes what's happening in a room</li>
<li>Learns entirely on its own from raw WiFi data — no cameras, no labeling, no human supervision needed</li>
<li>Recognizes rooms, detects intruders, identifies people, and classifies activities using only WiFi</li>
<li>Runs on an $8 ESP32 chip (the entire model fits in 55 KB of memory)</li>
<li>Produces both body pose tracking AND environment fingerprints in a single computation</li>
</ul>
<p dir="auto"><strong>Key Capabilities</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>What</th>
<th>How it works</th>
<th>Why it matters</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Self-supervised learning</strong></td>
<td>The model watches WiFi signals and teaches itself what "similar" and "different" look like, without any human-labeled data</td>
<td>Deploy anywhere — just plug in a WiFi sensor and wait 10 minutes</td>
</tr>
<tr>
<td><strong>Room identification</strong></td>
<td>Each room produces a distinct WiFi fingerprint pattern</td>
<td>Know which room someone is in without GPS or beacons</td>
</tr>
<tr>
<td><strong>Anomaly detection</strong></td>
<td>An unexpected person or event creates a fingerprint that doesn't match anything seen before</td>
<td>Automatic intrusion and fall detection as a free byproduct</td>
</tr>
<tr>
<td><strong>Person re-identification</strong></td>
<td>Each person disturbs WiFi in a slightly different way, creating a personal signature</td>
<td>Track individuals across sessions without cameras</td>
</tr>
<tr>
<td><strong>Environment adaptation</strong></td>
<td>MicroLoRA adapters (1,792 parameters per room) fine-tune the model for each new space</td>
<td>Adapts to a new room with minimal data — 93% less than retraining from scratch</td>
</tr>
<tr>
<td><strong>Memory preservation</strong></td>
<td>EWC++ regularization remembers what was learned during pretraining</td>
<td>Switching to a new task doesn't erase prior knowledge</td>
</tr>
<tr>
<td><strong>Hard-negative mining</strong></td>
<td>Training focuses on the most confusing examples to learn faster</td>
<td>Better accuracy with the same amount of training data</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Architecture</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="WiFi Signal [56 channels] → Transformer + Graph Neural Network
                                  ├→ 128-dim environment fingerprint (for search + identification)
                                  └→ 17-joint body pose (for human tracking)"><pre class="notranslate"><code>WiFi Signal [56 channels] → Transformer + Graph Neural Network
                                  ├→ 128-dim environment fingerprint (for search + identification)
                                  └→ 17-joint body pose (for human tracking)
</code></pre></div>
<p dir="auto"><strong>Quick Start</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Step 1: Learn from raw WiFi data (no labels needed)
cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50

# Step 2: Fine-tune with pose labels for full capability
cargo run -p wifi-densepose-sensing-server -- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf

# Step 3: Use the model — extract fingerprints from live WiFi
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --embed

# Step 4: Search — find similar environments or detect anomalies
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --build-index env"><pre><span class="pl-c"><span class="pl-c">#</span> Step 1: Learn from raw WiFi data (no labels needed)</span>
cargo run -p wifi-densepose-sensing-server -- --pretrain --dataset data/csi/ --pretrain-epochs 50

<span class="pl-c"><span class="pl-c">#</span> Step 2: Fine-tune with pose labels for full capability</span>
cargo run -p wifi-densepose-sensing-server -- --train --dataset data/mmfi/ --epochs 100 --save-rvf model.rvf

<span class="pl-c"><span class="pl-c">#</span> Step 3: Use the model — extract fingerprints from live WiFi</span>
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --embed

<span class="pl-c"><span class="pl-c">#</span> Step 4: Search — find similar environments or detect anomalies</span>
cargo run -p wifi-densepose-sensing-server -- --model model.rvf --build-index env</pre></div>
<p dir="auto"><strong>Training Modes</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Mode</th>
<th>What you need</th>
<th>What you get</th>
</tr>
</thead>
<tbody>
<tr>
<td>Self-Supervised</td>
<td>Just raw WiFi data</td>
<td>A model that understands WiFi signal structure</td>
</tr>
<tr>
<td>Supervised</td>
<td>WiFi data + body pose labels</td>
<td>Full pose tracking + environment fingerprints</td>
</tr>
<tr>
<td>Cross-Modal</td>
<td>WiFi data + camera footage</td>
<td>Fingerprints aligned with visual understanding</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Fingerprint Index Types</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Index</th>
<th>What it stores</th>
<th>Real-world use</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>env_fingerprint</code></td>
<td>Average room fingerprint</td>
<td>"Is this the kitchen or the bedroom?"</td>
</tr>
<tr>
<td><code>activity_pattern</code></td>
<td>Activity boundaries</td>
<td>"Is someone cooking, sleeping, or exercising?"</td>
</tr>
<tr>
<td><code>temporal_baseline</code></td>
<td>Normal conditions</td>
<td>"Something unusual just happened in this room"</td>
</tr>
<tr>
<td><code>person_track</code></td>
<td>Individual movement signatures</td>
<td>"Person A just entered the living room"</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Model Size</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Component</th>
<th>Parameters</th>
<th>Memory (on ESP32)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Transformer backbone</td>
<td>~28,000</td>
<td>28 KB</td>
</tr>
<tr>
<td>Embedding projection head</td>
<td>~25,000</td>
<td>25 KB</td>
</tr>
<tr>
<td>Per-room MicroLoRA adapter</td>
<td>~1,800</td>
<td>2 KB</td>
</tr>
<tr>
<td><strong>Total</strong></td>
<td><strong>~55,000</strong></td>
<td><strong>55 KB</strong> (of 520 KB available)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">The self-learning system builds on the <a href="#ai-backbone-ruvector">AI Backbone (RuVector)</a> signal-processing layer — attention, graph algorithms, and compression — adding contrastive learning on top.</p>
<p dir="auto">See <a href="docs/adr/ADR-024-contrastive-csi-embedding-model.md"><code>docs/adr/ADR-024-contrastive-csi-embedding-model.md</code></a> for full architectural details.</p>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📦 Installation</h2><a id="user-content--installation" class="anchor" aria-label="Permalink: 📦 Installation" href="#-installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Guided Installer</strong> — Interactive hardware detection and profile selection</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./install.sh"><pre>./install.sh</pre></div>
<p dir="auto">The installer walks through 7 steps: system detection, toolchain check, WiFi hardware scan, profile recommendation, dependency install, build, and verification.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Profile</th>
<th>What it installs</th>
<th>Size</th>
<th>Requirements</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>verify</code></td>
<td>Pipeline verification only</td>
<td>~5 MB</td>
<td>Python 3.8+</td>
</tr>
<tr>
<td><code>python</code></td>
<td>Full Python API server + sensing</td>
<td>~500 MB</td>
<td>Python 3.8+</td>
</tr>
<tr>
<td><code>rust</code></td>
<td>Rust pipeline (~810x faster)</td>
<td>~200 MB</td>
<td>Rust 1.70+</td>
</tr>
<tr>
<td><code>browser</code></td>
<td>WASM for in-browser execution</td>
<td>~10 MB</td>
<td>Rust + wasm-pack</td>
</tr>
<tr>
<td><code>iot</code></td>
<td>ESP32 sensor mesh + aggregator</td>
<td>varies</td>
<td>Rust + ESP-IDF</td>
</tr>
<tr>
<td><code>docker</code></td>
<td>Docker-based deployment</td>
<td>~1 GB</td>
<td>Docker</td>
</tr>
<tr>
<td><code>field</code></td>
<td>WiFi-Mat disaster response kit</td>
<td>~62 MB</td>
<td>Rust + wasm-pack</td>
</tr>
<tr>
<td><code>full</code></td>
<td>Everything available</td>
<td>~2 GB</td>
<td>All toolchains</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Non-interactive
./install.sh --profile rust --yes

# Hardware check only
./install.sh --check-only"><pre><span class="pl-c"><span class="pl-c">#</span> Non-interactive</span>
./install.sh --profile rust --yes

<span class="pl-c"><span class="pl-c">#</span> Hardware check only</span>
./install.sh --check-only</pre></div>
</details>
<details>
<summary><strong>From Source</strong> — Rust (primary) or Python</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/ruvnet/RuView.git
cd RuView

# Rust (primary — 810x faster)
cd rust-port/wifi-densepose-rs
cargo build --release
cargo test --workspace

# Python (legacy v1)
pip install -r requirements.txt
pip install -e .

# Or via pip
pip install wifi-densepose
pip install wifi-densepose[gpu]   # GPU acceleration
pip install wifi-densepose[all]   # All optional deps"><pre>git clone https://github.com/ruvnet/RuView.git
<span class="pl-c1">cd</span> RuView

<span class="pl-c"><span class="pl-c">#</span> Rust (primary — 810x faster)</span>
<span class="pl-c1">cd</span> rust-port/wifi-densepose-rs
cargo build --release
cargo <span class="pl-c1">test</span> --workspace

<span class="pl-c"><span class="pl-c">#</span> Python (legacy v1)</span>
pip install -r requirements.txt
pip install -e <span class="pl-c1">.</span>

<span class="pl-c"><span class="pl-c">#</span> Or via pip</span>
pip install wifi-densepose
pip install wifi-densepose[gpu]   <span class="pl-c"><span class="pl-c">#</span> GPU acceleration</span>
pip install wifi-densepose[all]   <span class="pl-c"><span class="pl-c">#</span> All optional deps</span></pre></div>
</details>
<details>
<summary><strong>Docker</strong> — Pre-built images, no toolchain needed</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Rust sensing server (132 MB — recommended)
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 -p 3001:3001 -p 5005:5005/udp ruvnet/wifi-densepose:latest

# Python sensing pipeline (569 MB)
docker pull ruvnet/wifi-densepose:python
docker run -p 8765:8765 -p 8080:8080 ruvnet/wifi-densepose:python

# Both via docker-compose
cd docker &amp;&amp; docker compose up

# Export RVF model
docker run --rm -v $(pwd):/out ruvnet/wifi-densepose:latest --export-rvf /out/model.rvf"><pre><span class="pl-c"><span class="pl-c">#</span> Rust sensing server (132 MB — recommended)</span>
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 -p 3001:3001 -p 5005:5005/udp ruvnet/wifi-densepose:latest

<span class="pl-c"><span class="pl-c">#</span> Python sensing pipeline (569 MB)</span>
docker pull ruvnet/wifi-densepose:python
docker run -p 8765:8765 -p 8080:8080 ruvnet/wifi-densepose:python

<span class="pl-c"><span class="pl-c">#</span> Both via docker-compose</span>
<span class="pl-c1">cd</span> docker <span class="pl-k">&amp;&amp;</span> docker compose up

<span class="pl-c"><span class="pl-c">#</span> Export RVF model</span>
docker run --rm -v <span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>:/out ruvnet/wifi-densepose:latest --export-rvf /out/model.rvf</pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Image</th>
<th>Tag</th>
<th>Platforms</th>
<th>Ports</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ruvnet/wifi-densepose</code></td>
<td><code>latest</code>, <code>rust</code></td>
<td>linux/amd64, linux/arm64</td>
<td>3000 (REST), 3001 (WS), 5005/udp (ESP32)</td>
</tr>
<tr>
<td><code>ruvnet/wifi-densepose</code></td>
<td><code>python</code></td>
<td>linux/amd64</td>
<td>8765 (WS), 8080 (UI)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>System Requirements</strong></summary>
<ul dir="auto">
<li><strong>Rust</strong>: 1.70+ (primary runtime — install via <a href="https://rustup.rs/" rel="nofollow">rustup</a>)</li>
<li><strong>Python</strong>: 3.8+ (for verification and legacy v1 API)</li>
<li><strong>OS</strong>: Linux (Ubuntu 18.04+), macOS (10.15+), Windows 10+</li>
<li><strong>Memory</strong>: Minimum 4GB RAM, Recommended 8GB+</li>
<li><strong>Storage</strong>: 2GB free space for models and data</li>
<li><strong>Network</strong>: WiFi interface with CSI capability (optional — installer detects what you have)</li>
<li><strong>GPU</strong>: Optional (NVIDIA CUDA or Apple Metal)</li>
</ul>
</details>
<details>
<summary><strong>Rust Crates</strong> — Individual crates on crates.io</summary>
<p dir="auto">The Rust workspace consists of 15 crates, all published to <a href="https://crates.io/" rel="nofollow">crates.io</a>:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Add individual crates to your Cargo.toml
cargo add wifi-densepose-core       # Types, traits, errors
cargo add wifi-densepose-signal     # CSI signal processing (6 SOTA algorithms)
cargo add wifi-densepose-nn         # Neural inference (ONNX, PyTorch, Candle)
cargo add wifi-densepose-vitals     # Vital sign extraction (breathing + heart rate)
cargo add wifi-densepose-mat        # Disaster response (MAT survivor detection)
cargo add wifi-densepose-hardware   # ESP32, Intel 5300, Atheros sensors
cargo add wifi-densepose-train      # Training pipeline (MM-Fi dataset)
cargo add wifi-densepose-wifiscan   # Multi-BSSID WiFi scanning
cargo add wifi-densepose-ruvector   # RuVector v2.0.4 integration layer (ADR-017)"><pre><span class="pl-c"><span class="pl-c">#</span> Add individual crates to your Cargo.toml</span>
cargo add wifi-densepose-core       <span class="pl-c"><span class="pl-c">#</span> Types, traits, errors</span>
cargo add wifi-densepose-signal     <span class="pl-c"><span class="pl-c">#</span> CSI signal processing (6 SOTA algorithms)</span>
cargo add wifi-densepose-nn         <span class="pl-c"><span class="pl-c">#</span> Neural inference (ONNX, PyTorch, Candle)</span>
cargo add wifi-densepose-vitals     <span class="pl-c"><span class="pl-c">#</span> Vital sign extraction (breathing + heart rate)</span>
cargo add wifi-densepose-mat        <span class="pl-c"><span class="pl-c">#</span> Disaster response (MAT survivor detection)</span>
cargo add wifi-densepose-hardware   <span class="pl-c"><span class="pl-c">#</span> ESP32, Intel 5300, Atheros sensors</span>
cargo add wifi-densepose-train      <span class="pl-c"><span class="pl-c">#</span> Training pipeline (MM-Fi dataset)</span>
cargo add wifi-densepose-wifiscan   <span class="pl-c"><span class="pl-c">#</span> Multi-BSSID WiFi scanning</span>
cargo add wifi-densepose-ruvector   <span class="pl-c"><span class="pl-c">#</span> RuVector v2.0.4 integration layer (ADR-017)</span></pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Crate</th>
<th>Description</th>
<th>RuVector</th>
<th>crates.io</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-core" rel="nofollow"><code>wifi-densepose-core</code></a></td>
<td>Foundation types, traits, and utilities</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-core" rel="nofollow"><img src="https://camo.githubusercontent.com/27ade5632d48a7e984a7531937b68d8b1f5992953645b6a68259da54c53a8ce1/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d636f72652e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-core.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-signal" rel="nofollow"><code>wifi-densepose-signal</code></a></td>
<td>SOTA CSI signal processing (SpotFi, FarSense, Widar 3.0)</td>
<td><code>mincut</code>, <code>attn-mincut</code>, <code>attention</code>, <code>solver</code></td>
<td><a href="https://crates.io/crates/wifi-densepose-signal" rel="nofollow"><img src="https://camo.githubusercontent.com/c65f8fe8773fac8657ff382e89aa6a3ebf7c733b92e1dfe476ce1e6fe986ab19/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d7369676e616c2e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-signal.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-nn" rel="nofollow"><code>wifi-densepose-nn</code></a></td>
<td>Multi-backend inference (ONNX, PyTorch, Candle)</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-nn" rel="nofollow"><img src="https://camo.githubusercontent.com/24eb0bebf0b6a25f988409f6536789ce5a24b1052a20c940ab7aa183583ff4a2/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d6e6e2e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-nn.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-train" rel="nofollow"><code>wifi-densepose-train</code></a></td>
<td>Training pipeline with MM-Fi dataset (NeurIPS 2023)</td>
<td><strong>All 5</strong></td>
<td><a href="https://crates.io/crates/wifi-densepose-train" rel="nofollow"><img src="https://camo.githubusercontent.com/62dbf27af80b4894c95ef7d3206a0decd523e4c330e755c953b034157b9ccc4f/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d747261696e2e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-train.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-mat" rel="nofollow"><code>wifi-densepose-mat</code></a></td>
<td>Mass Casualty Assessment Tool (disaster survivor detection)</td>
<td><code>solver</code>, <code>temporal-tensor</code></td>
<td><a href="https://crates.io/crates/wifi-densepose-mat" rel="nofollow"><img src="https://camo.githubusercontent.com/deddb5835645c6d76b01cb8e251744253eb9a0ae5c4f43a66853356de9d7a794/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d6d61742e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-mat.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow"><code>wifi-densepose-ruvector</code></a></td>
<td>RuVector v2.0.4 integration layer — 7 signal+MAT integration points (ADR-017)</td>
<td><strong>All 5</strong></td>
<td><a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow"><img src="https://camo.githubusercontent.com/33daf0f5f54af17d0193f4e533ddb051455495474682468091ba2f4034fc73a0/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d7275766563746f722e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-ruvector.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-vitals" rel="nofollow"><code>wifi-densepose-vitals</code></a></td>
<td>Vital signs: breathing (6-30 BPM), heart rate (40-120 BPM)</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-vitals" rel="nofollow"><img src="https://camo.githubusercontent.com/48f68dfb864f0bbd3c5004a37a096726e548e1db5fea8bfa97a00e47e8dcead5/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d766974616c732e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-vitals.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-hardware" rel="nofollow"><code>wifi-densepose-hardware</code></a></td>
<td>ESP32, Intel 5300, Atheros CSI sensor interfaces</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-hardware" rel="nofollow"><img src="https://camo.githubusercontent.com/bdb3f0af9e5b606a5286d94a9fc2f12dff7467babfc56c3eb6b4e23a365c4432/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d68617264776172652e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-hardware.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-wifiscan" rel="nofollow"><code>wifi-densepose-wifiscan</code></a></td>
<td>Multi-BSSID WiFi scanning (Windows, macOS, Linux)</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-wifiscan" rel="nofollow"><img src="https://camo.githubusercontent.com/7cb853ff127c311dfd5f3cbc1659d250e6522a3289be87ee811c6454668099a9/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d776966697363616e2e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-wifiscan.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-wasm" rel="nofollow"><code>wifi-densepose-wasm</code></a></td>
<td>WebAssembly bindings for browser deployment</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-wasm" rel="nofollow"><img src="https://camo.githubusercontent.com/ec1347143af10b89ba2526d35000a79fe196b760d7c810d5de577ff004ad877f/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d7761736d2e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-wasm.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-sensing-server" rel="nofollow"><code>wifi-densepose-sensing-server</code></a></td>
<td>Axum server: UDP ingestion, WebSocket broadcast</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-sensing-server" rel="nofollow"><img src="https://camo.githubusercontent.com/7b2d3cabe5389b4a19335c720f12c2f6882f526efd37c1cbf7bd01921ae9bb49/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d73656e73696e672d7365727665722e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-sensing-server.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-cli" rel="nofollow"><code>wifi-densepose-cli</code></a></td>
<td>Command-line tool for MAT disaster scanning</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-cli" rel="nofollow"><img src="https://camo.githubusercontent.com/afd4a8c6331dd2277f61f56e4d1eedfad1f94523f3f5612640e4e09e0814c21d/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d636c692e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-cli.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-api" rel="nofollow"><code>wifi-densepose-api</code></a></td>
<td>REST + WebSocket API layer</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-api" rel="nofollow"><img src="https://camo.githubusercontent.com/aa602e4a7b8d347ed60fef99844d8f19dfe00749dbde9837890ea21f42ea2bbd/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d6170692e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-api.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-config" rel="nofollow"><code>wifi-densepose-config</code></a></td>
<td>Configuration management</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-config" rel="nofollow"><img src="https://camo.githubusercontent.com/1cbedee25d358d745f29d6a35923a0fb4d4199330c30eb652d488a2fb4bb602f/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d636f6e6669672e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-config.svg" style="max-width: 100%;"></a></td>
</tr>
<tr>
<td><a href="https://crates.io/crates/wifi-densepose-db" rel="nofollow"><code>wifi-densepose-db</code></a></td>
<td>Database persistence (PostgreSQL, SQLite, Redis)</td>
<td>--</td>
<td><a href="https://crates.io/crates/wifi-densepose-db" rel="nofollow"><img src="https://camo.githubusercontent.com/66f6f999648c482edb6b8451fd56d60f220233720ad93961d9b7cac648d8e648/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f776966692d64656e7365706f73652d64622e737667" alt="crates.io" data-canonical-src="https://img.shields.io/crates/v/wifi-densepose-db.svg" style="max-width: 100%;"></a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">All crates integrate with <a href="https://github.com/ruvnet/ruvector">RuVector v2.0.4</a> — see <a href="#ai-backbone-ruvector">AI Backbone</a> below.</p>
<p dir="auto"><strong><a href="rust-port/wifi-densepose-rs/crates/ruv-neural/">rUv Neural</a></strong> — A separate 12-crate workspace for brain network topology analysis, neural decoding, and medical sensing. See <a href="#ruv-neural">rUv Neural</a> in Models &amp; Training.</p>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🚀 Quick Start</h2><a id="user-content--quick-start" class="anchor" aria-label="Permalink: 🚀 Quick Start" href="#-quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details open="">
<summary><strong>First API call in 3 commands</strong></summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">1. Install</h3><a id="user-content-1-install" class="anchor" aria-label="Permalink: 1. Install" href="#1-install"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Fastest path — Docker
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 ruvnet/wifi-densepose:latest

# Or from source (Rust)
./install.sh --profile rust --yes"><pre><span class="pl-c"><span class="pl-c">#</span> Fastest path — Docker</span>
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 ruvnet/wifi-densepose:latest

<span class="pl-c"><span class="pl-c">#</span> Or from source (Rust)</span>
./install.sh --profile rust --yes</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">2. Start the System</h3><a id="user-content-2-start-the-system" class="anchor" aria-label="Permalink: 2. Start the System" href="#2-start-the-system"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from wifi_densepose import WiFiDensePose

system = WiFiDensePose()
system.start()
poses = system.get_latest_poses()
print(f&quot;Detected {len(poses)} persons&quot;)
system.stop()"><pre><span class="pl-k">from</span> <span class="pl-s1">wifi_densepose</span> <span class="pl-k">import</span> <span class="pl-v">WiFiDensePose</span>

<span class="pl-s1">system</span> <span class="pl-c1">=</span> <span class="pl-en">WiFiDensePose</span>()
<span class="pl-s1">system</span>.<span class="pl-c1">start</span>()
<span class="pl-s1">poses</span> <span class="pl-c1">=</span> <span class="pl-s1">system</span>.<span class="pl-c1">get_latest_poses</span>()
<span class="pl-en">print</span>(<span class="pl-s">f"Detected <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-en">len</span>(<span class="pl-s1">poses</span>)<span class="pl-kos">}</span></span> persons"</span>)
<span class="pl-s1">system</span>.<span class="pl-c1">stop</span>()</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">3. REST API</h3><a id="user-content-3-rest-api" class="anchor" aria-label="Permalink: 3. REST API" href="#3-rest-api"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Health check
curl http://localhost:3000/health

# Latest sensing frame
curl http://localhost:3000/api/v1/sensing/latest

# Vital signs
curl http://localhost:3000/api/v1/vital-signs

# Pose estimation
curl http://localhost:3000/api/v1/pose/current

# Server info
curl http://localhost:3000/api/v1/info"><pre><span class="pl-c"><span class="pl-c">#</span> Health check</span>
curl http://localhost:3000/health

<span class="pl-c"><span class="pl-c">#</span> Latest sensing frame</span>
curl http://localhost:3000/api/v1/sensing/latest

<span class="pl-c"><span class="pl-c">#</span> Vital signs</span>
curl http://localhost:3000/api/v1/vital-signs

<span class="pl-c"><span class="pl-c">#</span> Pose estimation</span>
curl http://localhost:3000/api/v1/pose/current

<span class="pl-c"><span class="pl-c">#</span> Server info</span>
curl http://localhost:3000/api/v1/info</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">4. Real-time WebSocket</h3><a id="user-content-4-real-time-websocket" class="anchor" aria-label="Permalink: 4. Real-time WebSocket" href="#4-real-time-websocket"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import asyncio, websockets, json

async def stream():
    async with websockets.connect(&quot;ws://localhost:3001/ws/sensing&quot;) as ws:
        async for msg in ws:
            data = json.loads(msg)
            print(f&quot;Persons: {len(data.get('persons', []))}&quot;)

asyncio.run(stream())"><pre><span class="pl-k">import</span> <span class="pl-s1">asyncio</span>, <span class="pl-s1">websockets</span>, <span class="pl-s1">json</span>

<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">stream</span>():
    <span class="pl-k">async</span> <span class="pl-k">with</span> <span class="pl-s1">websockets</span>.<span class="pl-c1">connect</span>(<span class="pl-s">"ws://localhost:3001/ws/sensing"</span>) <span class="pl-k">as</span> <span class="pl-s1">ws</span>:
        <span class="pl-k">async</span> <span class="pl-k">for</span> <span class="pl-s1">msg</span> <span class="pl-c1">in</span> <span class="pl-s1">ws</span>:
            <span class="pl-s1">data</span> <span class="pl-c1">=</span> <span class="pl-s1">json</span>.<span class="pl-c1">loads</span>(<span class="pl-s1">msg</span>)
            <span class="pl-en">print</span>(<span class="pl-s">f"Persons: <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-en">len</span>(<span class="pl-s1">data</span>.<span class="pl-c1">get</span>(<span class="pl-s">'persons'</span>, []))<span class="pl-kos">}</span></span>"</span>)

<span class="pl-s1">asyncio</span>.<span class="pl-c1">run</span>(<span class="pl-en">stream</span>())</pre></div>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📋 Table of Contents</h2><a id="user-content--table-of-contents" class="anchor" aria-label="Permalink: 📋 Table of Contents" href="#-table-of-contents"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details open="">
<summary><strong>📡 Signal Processing &amp; Sensing</strong> — From raw WiFi frames to vital signs</summary>
<p dir="auto">The signal processing stack transforms raw WiFi Channel State Information into actionable human sensing data. Starting from 56-192 subcarrier complex values captured at 20 Hz, the pipeline applies research-grade algorithms (SpotFi phase correction, Hampel outlier rejection, Fresnel zone modeling) to extract breathing rate, heart rate, motion level, and multi-person body pose — all in pure Rust with zero external ML dependencies.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Section</th>
<th>Description</th>
<th>Docs</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#key-features">Key Features</a></td>
<td>Sensing, Intelligence, and Performance &amp; Deployment capabilities</td>
<td>—</td>
</tr>
<tr>
<td><a href="#how-it-works">How It Works</a></td>
<td>End-to-end pipeline: radio waves → CSI capture → signal processing → AI → pose + vitals</td>
<td>—</td>
</tr>
<tr>
<td><a href="#esp32-s3-hardware-pipeline">ESP32-S3 Hardware Pipeline</a></td>
<td>20 Hz CSI streaming, binary frame parsing, flash &amp; provision</td>
<td><a href="docs/adr/ADR-018-esp32-dev-implementation.md">ADR-018</a> · <a href="https://github.com/ruvnet/RuView/issues/34" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/34/hovercard">Tutorial #34</a></td>
</tr>
<tr>
<td><a href="#vital-sign-detection">Vital Sign Detection</a></td>
<td>Breathing 6-30 BPM, heartbeat 40-120 BPM, FFT peak detection</td>
<td><a href="docs/adr/ADR-021-vital-sign-detection-rvdna-pipeline.md">ADR-021</a></td>
</tr>
<tr>
<td><a href="#wifi-scan-domain-layer">WiFi Scan Domain Layer</a></td>
<td>8-stage RSSI pipeline, multi-BSSID fingerprinting, Windows WiFi</td>
<td><a href="docs/adr/ADR-022-windows-wifi-enhanced-fidelity-ruvector.md">ADR-022</a> · <a href="https://github.com/ruvnet/RuView/issues/36" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/36/hovercard">Tutorial #36</a></td>
</tr>
<tr>
<td><a href="#wifi-mat-disaster-response">WiFi-Mat Disaster Response</a></td>
<td>Search &amp; rescue, START triage, 3D localization through debris</td>
<td><a href="docs/adr/ADR-001-wifi-mat-disaster-detection.md">ADR-001</a> · <a href="docs/wifi-mat-user-guide.md">User Guide</a></td>
</tr>
<tr>
<td><a href="#sota-signal-processing">SOTA Signal Processing</a></td>
<td>SpotFi, Hampel, Fresnel, STFT spectrogram, subcarrier selection, BVP</td>
<td><a href="docs/adr/ADR-014-sota-signal-processing.md">ADR-014</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>🧠 Models &amp; Training</strong> — DensePose pipeline, RVF containers, SONA adaptation, RuVector integration</summary>
<p dir="auto">The neural pipeline uses a graph transformer with cross-attention to map CSI feature matrices to 17 COCO body keypoints and DensePose UV coordinates. Models are packaged as single-file <code>.rvf</code> containers with progressive loading (Layer A instant, Layer B warm, Layer C full). SONA (Self-Optimizing Neural Architecture) enables continuous on-device adaptation via micro-LoRA + EWC++ without catastrophic forgetting. Signal processing is powered by 5 <a href="https://github.com/ruvnet/ruvector">RuVector</a> crates (v2.0.4) with 7 integration points across the Rust workspace, plus 6 additional vendored crates for inference and graph intelligence.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Section</th>
<th>Description</th>
<th>Docs</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#rvf-model-container">RVF Model Container</a></td>
<td>Binary packaging with Ed25519 signing, progressive 3-layer loading, SIMD quantization</td>
<td><a href="docs/adr/ADR-023-trained-densepose-model-ruvector-pipeline.md">ADR-023</a></td>
</tr>
<tr>
<td><a href="#training--fine-tuning">Training &amp; Fine-Tuning</a></td>
<td>8-phase pure Rust pipeline (7,832 lines), MM-Fi/Wi-Pose pre-training, 6-term composite loss, SONA LoRA</td>
<td><a href="docs/adr/ADR-023-trained-densepose-model-ruvector-pipeline.md">ADR-023</a></td>
</tr>
<tr>
<td><a href="#ruvector-crates">RuVector Crates</a></td>
<td>11 vendored Rust crates from <a href="https://github.com/ruvnet/ruvector">ruvector</a>: attention, min-cut, solver, GNN, HNSW, temporal compression, sparse inference</td>
<td><a href="https://github.com/ruvnet/ruvector">GitHub</a> · <a href="vendor/ruvector/">Source</a></td>
</tr>
<tr>
<td><a href="#ruv-neural">rUv Neural</a></td>
<td>12-crate brain topology analysis ecosystem: neural decoding, quantum sensor integration, cognitive state classification, BCI output</td>
<td><a href="rust-port/wifi-densepose-rs/crates/ruv-neural/README.md">README</a></td>
</tr>
<tr>
<td><a href="#ai-backbone-ruvector">AI Backbone (RuVector)</a></td>
<td>5 AI capabilities replacing hand-tuned thresholds: attention, graph min-cut, sparse solvers, tiered compression</td>
<td><a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow">crates.io</a></td>
</tr>
<tr>
<td><a href="#self-learning-wifi-ai-adr-024">Self-Learning WiFi AI (ADR-024)</a></td>
<td>Contrastive self-supervised learning, room fingerprinting, anomaly detection, 55 KB model</td>
<td><a href="docs/adr/ADR-024-contrastive-csi-embedding-model.md">ADR-024</a></td>
</tr>
<tr>
<td><a href="docs/adr/ADR-027-cross-environment-domain-generalization.md">Cross-Environment Generalization (ADR-027)</a></td>
<td>Domain-adversarial training, geometry-conditioned inference, hardware normalization, zero-shot deployment</td>
<td><a href="docs/adr/ADR-027-cross-environment-domain-generalization.md">ADR-027</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>🖥️ Usage &amp; Configuration</strong> — CLI flags, API endpoints, hardware setup</summary>
<p dir="auto">The Rust sensing server is the primary interface, offering a comprehensive CLI with flags for data source selection, model loading, training, benchmarking, and RVF export. A REST API (Axum) and WebSocket server provide real-time data access. The Python v1 CLI remains available for legacy workflows.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Section</th>
<th>Description</th>
<th>Docs</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#cli-usage">CLI Usage</a></td>
<td><code>--source</code>, <code>--train</code>, <code>--benchmark</code>, <code>--export-rvf</code>, <code>--model</code>, <code>--progressive</code></td>
<td>—</td>
</tr>
<tr>
<td><a href="#rest-api--websocket">REST API &amp; WebSocket</a></td>
<td>6 REST endpoints (sensing, vitals, BSSID, SONA), WebSocket real-time stream</td>
<td>—</td>
</tr>
<tr>
<td><a href="#hardware-support-1">Hardware Support</a></td>
<td>ESP32-S3 ($8), Intel 5300 ($15), Atheros AR9580 ($20), Windows RSSI ($0)</td>
<td><a href="docs/adr/ADR-012-esp32-csi-sensor-mesh.md">ADR-012</a> · <a href="docs/adr/ADR-013-feature-level-sensing-commodity-gear.md">ADR-013</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>⚙️ Development &amp; Testing</strong> — 542+ tests, CI, deployment</summary>
<p dir="auto">The project maintains 542+ pure-Rust tests across 7 crate suites with zero mocks — every test runs against real algorithm implementations. Hardware-free simulation mode (<code>--source simulate</code>) enables full-stack testing without physical devices. Docker images are published on Docker Hub for zero-setup deployment.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Section</th>
<th>Description</th>
<th>Docs</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#testing">Testing</a></td>
<td>7 test suites: sensing-server (229), signal (83), mat (139), wifiscan (91), RVF (16), vitals (18)</td>
<td>—</td>
</tr>
<tr>
<td><a href="#deployment">Deployment</a></td>
<td>Docker images (132 MB Rust / 569 MB Python), docker-compose, env vars</td>
<td>—</td>
</tr>
<tr>
<td><a href="#contributing">Contributing</a></td>
<td>Fork → branch → test → PR workflow, Rust and Python dev setup</td>
<td>—</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>📊 Performance &amp; Benchmarks</strong> — Measured throughput, latency, resource usage</summary>
<p dir="auto">All benchmarks are measured on the Rust sensing server using <code>cargo bench</code> and the built-in <code>--benchmark</code> CLI flag. The Rust v2 implementation delivers 810x end-to-end speedup over the Python v1 baseline, with motion detection reaching 5,400x improvement. The vital sign detector processes 11,665 frames/second in a single-threaded benchmark.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Section</th>
<th>Description</th>
<th>Key Metric</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#performance-metrics">Performance Metrics</a></td>
<td>Vital signs, CSI pipeline, motion detection, Docker image, memory</td>
<td>11,665 fps vitals · 54K fps pipeline</td>
</tr>
<tr>
<td><a href="#python-vs-rust">Rust vs Python</a></td>
<td>Side-by-side benchmarks across 5 operations</td>
<td><strong>810x</strong> full pipeline speedup</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>📄 Meta</strong> — License, changelog, support</summary>
<p dir="auto">WiFi DensePose is MIT-licensed open source, developed by <a href="https://github.com/ruvnet">ruvnet</a>. The project has been in active development since March 2025, with 3 major releases delivering the Rust port, SOTA signal processing, disaster response module, and end-to-end training pipeline.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Section</th>
<th>Description</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#changelog">Changelog</a></td>
<td>v3.0.0 (AETHER AI + Docker), v2.0.0 (Rust port + SOTA + WiFi-Mat)</td>
<td><a href="CHANGELOG.md">CHANGELOG.md</a></td>
</tr>
<tr>
<td><a href="#license">License</a></td>
<td>MIT License</td>
<td><a href="LICENSE">LICENSE</a></td>
</tr>
<tr>
<td><a href="#support">Support</a></td>
<td>Bug reports, feature requests, community discussion</td>
<td><a href="https://github.com/ruvnet/RuView/issues">Issues</a> · <a href="https://github.com/ruvnet/RuView/discussions">Discussions</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<hr>
<details>
<summary><strong>🌍 Cross-Environment Generalization (ADR-027 — Project MERIDIAN)</strong> — Train once, deploy in any room without retraining</summary>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>What</th>
<th>How it works</th>
<th>Why it matters</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Gradient Reversal Layer</strong></td>
<td>An adversarial classifier tries to guess which room the signal came from; the main network is trained to fool it</td>
<td>Forces the model to discard room-specific shortcuts</td>
</tr>
<tr>
<td><strong>Geometry Encoder (FiLM)</strong></td>
<td>Transmitter/receiver positions are Fourier-encoded and injected as scale+shift conditioning on every layer</td>
<td>The model knows <em>where</em> the hardware is, so it doesn't need to memorize layout</td>
</tr>
<tr>
<td><strong>Hardware Normalizer</strong></td>
<td>Resamples any chipset's CSI to a canonical 56-subcarrier format with standardized amplitude</td>
<td>Intel 5300 and ESP32 data look identical to the model</td>
</tr>
<tr>
<td><strong>Virtual Domain Augmentation</strong></td>
<td>Generates synthetic environments with random room scale, wall reflections, scatterers, and noise profiles</td>
<td>Training sees 1000s of rooms even with data from just 2-3</td>
</tr>
<tr>
<td><strong>Rapid Adaptation (TTT)</strong></td>
<td>Contrastive test-time training with LoRA weight generation from a few unlabeled frames</td>
<td>Zero-shot deployment — the model self-tunes on arrival</td>
</tr>
<tr>
<td><strong>Cross-Domain Evaluator</strong></td>
<td>Leave-one-out evaluation across all training environments with per-environment PCK/OKS metrics</td>
<td>Proves generalization, not just memorization</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Architecture</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CSI Frame [any chipset]
    │
    ▼
HardwareNormalizer ──→ canonical 56 subcarriers, N(0,1) amplitude
    │
    ▼
CSI Encoder (existing) ──→ latent features
    │
    ├──→ Pose Head ──→ 17-joint pose (environment-invariant)
    │
    ├──→ Gradient Reversal Layer ──→ Domain Classifier (adversarial)
    │         λ ramps 0→1 via cosine/exponential schedule
    │
    └──→ Geometry Encoder ──→ FiLM conditioning (scale + shift)
              Fourier positional encoding → DeepSets → per-layer modulation"><pre class="notranslate"><code>CSI Frame [any chipset]
    │
    ▼
HardwareNormalizer ──→ canonical 56 subcarriers, N(0,1) amplitude
    │
    ▼
CSI Encoder (existing) ──→ latent features
    │
    ├──→ Pose Head ──→ 17-joint pose (environment-invariant)
    │
    ├──→ Gradient Reversal Layer ──→ Domain Classifier (adversarial)
    │         λ ramps 0→1 via cosine/exponential schedule
    │
    └──→ Geometry Encoder ──→ FiLM conditioning (scale + shift)
              Fourier positional encoding → DeepSets → per-layer modulation
</code></pre></div>
<p dir="auto"><strong>Security hardening:</strong></p>
<ul dir="auto">
<li>Bounded calibration buffer (max 10,000 frames) prevents memory exhaustion</li>
<li><code>adapt()</code> returns <code>Result&lt;_, AdaptError&gt;</code> — no panics on bad input</li>
<li>Atomic instance counter ensures unique weight initialization across threads</li>
<li>Division-by-zero guards on all augmentation parameters</li>
</ul>
<p dir="auto">See <a href="docs/adr/ADR-027-cross-environment-domain-generalization.md"><code>docs/adr/ADR-027-cross-environment-domain-generalization.md</code></a> for full architectural details.</p>
</details>
<details>
<summary><strong>🔍 Independent Capability Audit (ADR-028)</strong> — 1,031 tests, SHA-256 proof, self-verifying witness bundle</summary>
<p dir="auto">A <a href="docs/adr/ADR-028-esp32-capability-audit.md">3-agent parallel audit</a> independently verified every claim in this repository — ESP32 hardware, signal processing, neural networks, training pipeline, deployment, and security. Results:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Rust tests:     1,031 passed, 0 failed
Python proof:   VERDICT: PASS (SHA-256: 8c0680d7...)
Bundle verify:  7/7 checks PASS"><pre class="notranslate"><code>Rust tests:     1,031 passed, 0 failed
Python proof:   VERDICT: PASS (SHA-256: 8c0680d7...)
Bundle verify:  7/7 checks PASS
</code></pre></div>
<p dir="auto"><strong>33-row attestation matrix:</strong> 31 capabilities verified YES, 2 not measured at audit time (benchmark throughput, Kubernetes deploy).</p>
<p dir="auto"><strong>Verify it yourself</strong> (no hardware needed):</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Run all tests
cd rust-port/wifi-densepose-rs &amp;&amp; cargo test --workspace --no-default-features

# Run the deterministic proof
python v1/data/proof/verify.py

# Generate + verify the witness bundle
bash scripts/generate-witness-bundle.sh
cd dist/witness-bundle-ADR028-*/ &amp;&amp; bash VERIFY.sh"><pre><span class="pl-c"><span class="pl-c">#</span> Run all tests</span>
<span class="pl-c1">cd</span> rust-port/wifi-densepose-rs <span class="pl-k">&amp;&amp;</span> cargo <span class="pl-c1">test</span> --workspace --no-default-features

<span class="pl-c"><span class="pl-c">#</span> Run the deterministic proof</span>
python v1/data/proof/verify.py

<span class="pl-c"><span class="pl-c">#</span> Generate + verify the witness bundle</span>
bash scripts/generate-witness-bundle.sh
<span class="pl-c1">cd</span> dist/witness-bundle-ADR028-<span class="pl-k">*</span>/ <span class="pl-k">&amp;&amp;</span> bash VERIFY.sh</pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Document</th>
<th>What it contains</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="docs/adr/ADR-028-esp32-capability-audit.md">ADR-028</a></td>
<td>Full audit: ESP32 specs, signal algorithms, NN architectures, training phases, deployment infra</td>
</tr>
<tr>
<td><a href="docs/WITNESS-LOG-028.md">Witness Log</a></td>
<td>11 reproducible verification steps + 33-row attestation matrix with evidence per row</td>
</tr>
<tr>
<td><a href="scripts/generate-witness-bundle.sh"><code>generate-witness-bundle.sh</code></a></td>
<td>Creates self-contained tar.gz with test logs, proof output, firmware hashes, crate versions, VERIFY.sh</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>📡 Multistatic Sensing (ADR-029/030/031 — Project RuvSense + RuView)</strong> — Multiple ESP32 nodes fuse viewpoints for production-grade pose, tracking, and exotic sensing</summary>
<p dir="auto">A single WiFi receiver can track people, but has blind spots — limbs behind the torso are invisible, depth is ambiguous, and two people at similar range create overlapping signals. RuvSense solves this by coordinating multiple ESP32 nodes into a <strong>multistatic mesh</strong> where every node acts as both transmitter and receiver, creating N×(N-1) measurement links from N devices.</p>
<p dir="auto"><strong>What it does in plain terms:</strong></p>
<ul dir="auto">
<li>4 ESP32-S3 nodes ($48 total) provide 12 TX-RX measurement links covering 360 degrees</li>
<li>Each node hops across WiFi channels 1/6/11, tripling effective bandwidth from 20→60 MHz</li>
<li>Coherence gating rejects noisy frames automatically — no manual tuning, stable for days</li>
<li>Two-person tracking at 20 Hz with zero identity swaps over 10 minutes</li>
<li>The room itself becomes a persistent model — the system remembers, predicts, and explains</li>
</ul>
<p dir="auto"><strong>Three ADRs, one pipeline:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>ADR</th>
<th>Codename</th>
<th>What it adds</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="docs/adr/ADR-029-ruvsense-multistatic-sensing-mode.md">ADR-029</a></td>
<td><strong>RuvSense</strong></td>
<td>Channel hopping, TDM protocol, multi-node fusion, coherence gating, 17-keypoint Kalman tracker</td>
</tr>
<tr>
<td><a href="docs/adr/ADR-030-ruvsense-persistent-field-model.md">ADR-030</a></td>
<td><strong>RuvSense Field</strong></td>
<td>Room electromagnetic eigenstructure (SVD), RF tomography, longitudinal drift detection, intention prediction, gesture recognition, adversarial detection</td>
</tr>
<tr>
<td><a href="docs/adr/ADR-031-ruview-sensing-first-rf-mode.md">ADR-031</a></td>
<td><strong>RuView</strong></td>
<td>Cross-viewpoint attention with geometric bias, viewpoint diversity optimization, embedding-level fusion</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Architecture</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="4x ESP32-S3 nodes ($48)     TDM: each transmits in turn, all others receive
        │                    Channel hop: ch1→ch6→ch11 per dwell (50ms)
        ▼
Per-Node Signal Processing   Phase sanitize → Hampel → BVP → subcarrier select
        │                    (ADR-014, unchanged per viewpoint)
        ▼
Multi-Band Frame Fusion      3 channels × 56 subcarriers = 168 virtual subcarriers
        │                    Cross-channel phase alignment via NeumannSolver
        ▼
Multistatic Viewpoint Fusion  N nodes → attention-weighted fusion → single embedding
        │                    Geometric bias from node placement angles
        ▼
Coherence Gate               Accept / PredictOnly / Reject / Recalibrate
        │                    Prevents model drift, stable for days
        ▼
Persistent Field Model       SVD baseline → body = observation - environment
        │                    RF tomography, drift detection, intention signals
        ▼
Pose Tracker + DensePose     17-keypoint Kalman, re-ID via AETHER embeddings
                             Multi-person min-cut separation, zero ID swaps"><pre class="notranslate"><code>4x ESP32-S3 nodes ($48)     TDM: each transmits in turn, all others receive
        │                    Channel hop: ch1→ch6→ch11 per dwell (50ms)
        ▼
Per-Node Signal Processing   Phase sanitize → Hampel → BVP → subcarrier select
        │                    (ADR-014, unchanged per viewpoint)
        ▼
Multi-Band Frame Fusion      3 channels × 56 subcarriers = 168 virtual subcarriers
        │                    Cross-channel phase alignment via NeumannSolver
        ▼
Multistatic Viewpoint Fusion  N nodes → attention-weighted fusion → single embedding
        │                    Geometric bias from node placement angles
        ▼
Coherence Gate               Accept / PredictOnly / Reject / Recalibrate
        │                    Prevents model drift, stable for days
        ▼
Persistent Field Model       SVD baseline → body = observation - environment
        │                    RF tomography, drift detection, intention signals
        ▼
Pose Tracker + DensePose     17-keypoint Kalman, re-ID via AETHER embeddings
                             Multi-person min-cut separation, zero ID swaps
</code></pre></div>
<p dir="auto"><strong>Seven Exotic Sensing Tiers (ADR-030)</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Tier</th>
<th>Capability</th>
<th>What it detects</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Field Normal Modes</td>
<td>Room electromagnetic eigenstructure via SVD</td>
</tr>
<tr>
<td>2</td>
<td>Coarse RF Tomography</td>
<td>3D occupancy volume from link attenuations</td>
</tr>
<tr>
<td>3</td>
<td>Intention Lead Signals</td>
<td>Pre-movement prediction 200-500ms before action</td>
</tr>
<tr>
<td>4</td>
<td>Longitudinal Biomechanics</td>
<td>Personal movement changes over days/weeks</td>
</tr>
<tr>
<td>5</td>
<td>Cross-Room Continuity</td>
<td>Identity preserved across rooms without cameras</td>
</tr>
<tr>
<td>6</td>
<td>Invisible Interaction</td>
<td>Multi-user gesture control through walls</td>
</tr>
<tr>
<td>7</td>
<td>Adversarial Detection</td>
<td>Physically impossible signal identification</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Acceptance Test</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Metric</th>
<th>Threshold</th>
<th>What it proves</th>
</tr>
</thead>
<tbody>
<tr>
<td>Torso keypoint jitter</td>
<td>&lt; 30mm RMS</td>
<td>Precision sufficient for applications</td>
</tr>
<tr>
<td>Identity swaps</td>
<td>0 over 10 minutes (12,000 frames)</td>
<td>Reliable multi-person tracking</td>
</tr>
<tr>
<td>Update rate</td>
<td>20 Hz (50ms cycle)</td>
<td>Real-time response</td>
</tr>
<tr>
<td>Breathing SNR</td>
<td>&gt; 10 dB at 3m</td>
<td>Small-motion sensitivity confirmed</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>New Rust modules (9,000+ lines)</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Crate</th>
<th>New modules</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>wifi-densepose-signal</code></td>
<td><code>ruvsense/</code> (10 modules)</td>
<td>Multiband fusion, phase alignment, multistatic fusion, coherence, field model, tomography, longitudinal drift, intention detection</td>
</tr>
<tr>
<td><code>wifi-densepose-ruvector</code></td>
<td><code>viewpoint/</code> (5 modules)</td>
<td>Cross-viewpoint attention with geometric bias, diversity index, coherence gating, fusion orchestrator</td>
</tr>
<tr>
<td><code>wifi-densepose-hardware</code></td>
<td><code>esp32/tdm.rs</code></td>
<td>TDM sensing protocol, sync beacons, clock drift compensation</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Firmware extensions (C, backward-compatible)</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>File</th>
<th>Addition</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>csi_collector.c</code></td>
<td>Channel hop table, timer-driven hop, NDP injection stub</td>
</tr>
<tr>
<td><code>nvs_config.c</code></td>
<td>5 new NVS keys: hop_count, channel_list, dwell_ms, tdm_slot, tdm_node_count</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>DDD Domain Model</strong> — 6 bounded contexts: Multistatic Sensing, Coherence, Pose Tracking, Field Model, Cross-Room Identity, Adversarial Detection. Full specification: <a href="docs/ddd/ruvsense-domain-model.md"><code>docs/ddd/ruvsense-domain-model.md</code></a>.</p>
<p dir="auto">See the ADR documents for full architectural details, GOAP integration plans, and research references.</p>
</details>
<details>
<summary><b>🔮 Signal-Line Protocol (CRV)</b></summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">6-Stage CSI Signal Line</h3><a id="user-content-6-stage-csi-signal-line" class="anchor" aria-label="Permalink: 6-Stage CSI Signal Line" href="#6-stage-csi-signal-line"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Maps the CRV (Coordinate Remote Viewing) signal-line methodology to WiFi CSI processing via <code>ruvector-crv</code>:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Stage</th>
<th>CRV Name</th>
<th>WiFi CSI Mapping</th>
<th>ruvector Component</th>
</tr>
</thead>
<tbody>
<tr>
<td>I</td>
<td>Ideograms</td>
<td>Raw CSI gestalt (manmade/natural/movement/energy)</td>
<td>Poincare ball hyperbolic embeddings</td>
</tr>
<tr>
<td>II</td>
<td>Sensory</td>
<td>Amplitude textures, phase patterns, frequency colors</td>
<td>Multi-head attention vectors</td>
</tr>
<tr>
<td>III</td>
<td>Dimensional</td>
<td>AP mesh spatial topology, node geometry</td>
<td>GNN graph topology</td>
</tr>
<tr>
<td>IV</td>
<td>Emotional/AOL</td>
<td>Coherence gating — signal vs noise separation</td>
<td>SNN temporal encoding</td>
</tr>
<tr>
<td>V</td>
<td>Interrogation</td>
<td>Cross-stage probing — query pose against CSI history</td>
<td>Differentiable search</td>
</tr>
<tr>
<td>VI</td>
<td>3D Model</td>
<td>Composite person estimation, MinCut partitioning</td>
<td>Graph partitioning</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Cross-Session Convergence</strong>: When multiple AP clusters observe the same person, CRV convergence analysis finds agreement in their signal embeddings — directly mapping to cross-room identity continuity.</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use wifi_densepose_ruvector::crv::WifiCrvPipeline;

let mut pipeline = WifiCrvPipeline::new(WifiCrvConfig::default());
pipeline.create_session(&quot;room-a&quot;, &quot;person-001&quot;)?;

// Process CSI frames through 6-stage pipeline
let result = pipeline.process_csi_frame(&quot;room-a&quot;, &amp;amplitudes, &amp;phases)?;
// result.gestalt = Movement, confidence = 0.87
// result.sensory_embedding = [0.12, -0.34, ...]

// Cross-room identity matching via convergence
let convergence = pipeline.find_cross_room_convergence(&quot;person-001&quot;, 0.75)?;"><pre><span class="pl-k">use</span> wifi_densepose_ruvector<span class="pl-kos">::</span>crv<span class="pl-kos">::</span><span class="pl-v">WifiCrvPipeline</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> <span class="pl-k">mut</span> pipeline = <span class="pl-smi">WifiCrvPipeline</span><span class="pl-kos">::</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-smi">WifiCrvConfig</span><span class="pl-kos">::</span><span class="pl-en">default</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
pipeline<span class="pl-kos">.</span><span class="pl-en">create_session</span><span class="pl-kos">(</span><span class="pl-s">"room-a"</span><span class="pl-kos">,</span> <span class="pl-s">"person-001"</span><span class="pl-kos">)</span>?<span class="pl-kos">;</span>

<span class="pl-c">// Process CSI frames through 6-stage pipeline</span>
<span class="pl-k">let</span> result = pipeline<span class="pl-kos">.</span><span class="pl-en">process_csi_frame</span><span class="pl-kos">(</span><span class="pl-s">"room-a"</span><span class="pl-kos">,</span> <span class="pl-c1">&amp;</span>amplitudes<span class="pl-kos">,</span> <span class="pl-c1">&amp;</span>phases<span class="pl-kos">)</span>?<span class="pl-kos">;</span>
<span class="pl-c">// result.gestalt = Movement, confidence = 0.87</span>
<span class="pl-c">// result.sensory_embedding = [0.12, -0.34, ...]</span>

<span class="pl-c">// Cross-room identity matching via convergence</span>
<span class="pl-k">let</span> convergence = pipeline<span class="pl-kos">.</span><span class="pl-en">find_cross_room_convergence</span><span class="pl-kos">(</span><span class="pl-s">"person-001"</span><span class="pl-kos">,</span> <span class="pl-c1">0.75</span><span class="pl-kos">)</span>?<span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Architecture</strong>:</p>
<ul dir="auto">
<li><code>CsiGestaltClassifier</code> — Maps CSI amplitude/phase patterns to 6 gestalt types</li>
<li><code>CsiSensoryEncoder</code> — Extracts texture/color/temperature/luminosity features from subcarriers</li>
<li><code>MeshTopologyEncoder</code> — Encodes AP mesh as GNN graph (Stage III)</li>
<li><code>CoherenceAolDetector</code> — Maps coherence gate states to AOL noise detection (Stage IV)</li>
<li><code>WifiCrvPipeline</code> — Orchestrates all 6 stages into unified sensing session</li>
</ul>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📡 Signal Processing &amp; Sensing</h2><a id="user-content--signal-processing--sensing" class="anchor" aria-label="Permalink: 📡 Signal Processing &amp; Sensing" href="#-signal-processing--sensing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><a id="user-content-esp32-s3-hardware-pipeline"></a><strong>📡 ESP32-S3 Hardware Pipeline (ADR-018)</strong> — 28 Hz CSI streaming, flash &amp; provision</summary>
<p dir="auto">A single ESP32-S3 board (~$9) captures WiFi signal data 28 times per second and streams it over UDP. A host server can visualize and record the data, but the ESP32 can also run on its own — detecting presence, measuring breathing and heart rate, and alerting on falls without any server at all.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ESP32-S3 node                    UDP/5005        Host server (optional)
┌───────────────────────┐      ──────────&gt;      ┌──────────────────────┐
│ Captures WiFi signals │      binary frames    │ Parses frames        │
│ 28 Hz, up to 192 sub- │      or 32-byte       │ Visualizes poses     │
│ carriers per frame     │      vitals packets   │ Records CSI data     │
│                        │                       │ REST API + WebSocket │
│ On-device (optional):  │                       └──────────────────────┘
│  Presence detection    │
│  Breathing + heart rate│
│  Fall detection        │
│  WASM custom modules   │
└───────────────────────┘"><pre class="notranslate"><code>ESP32-S3 node                    UDP/5005        Host server (optional)
┌───────────────────────┐      ──────────&gt;      ┌──────────────────────┐
│ Captures WiFi signals │      binary frames    │ Parses frames        │
│ 28 Hz, up to 192 sub- │      or 32-byte       │ Visualizes poses     │
│ carriers per frame     │      vitals packets   │ Records CSI data     │
│                        │                       │ REST API + WebSocket │
│ On-device (optional):  │                       └──────────────────────┘
│  Presence detection    │
│  Breathing + heart rate│
│  Fall detection        │
│  WASM custom modules   │
└───────────────────────┘
</code></pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Metric</th>
<th>Measured on hardware</th>
</tr>
</thead>
<tbody>
<tr>
<td>CSI frame rate</td>
<td>28.5 Hz (channel 5, BW20)</td>
</tr>
<tr>
<td>Subcarriers per frame</td>
<td>64 / 128 / 192 (depends on WiFi mode)</td>
</tr>
<tr>
<td>UDP latency</td>
<td>&lt; 1 ms on local network</td>
</tr>
<tr>
<td>Presence detection range</td>
<td>Reliable at 3 m through walls</td>
</tr>
<tr>
<td>Binary size</td>
<td>947 KB (fits in 1 MB flash partition)</td>
</tr>
<tr>
<td>Boot to ready</td>
<td>~3.9 seconds</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Flash and provision</h3><a id="user-content-flash-and-provision" class="anchor" aria-label="Permalink: Flash and provision" href="#flash-and-provision"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Download a pre-built binary — no build toolchain needed:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Release</th>
<th>What's included</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/ruvnet/RuView/releases/tag/v0.4.1-esp32">v0.4.1</a></td>
<td><strong>Stable</strong> — CSI build fix, compile guard, AMOLED display, edge intelligence (<a href="docs/adr/ADR-057-firmware-csi-build-guard.md">ADR-057</a>)</td>
<td><code>v0.4.1-esp32</code></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/RuView/releases/tag/v0.3.0-alpha-esp32">v0.3.0-alpha</a></td>
<td>Alpha — adds on-device edge intelligence and WASM modules (<a href="docs/adr/ADR-039-esp32-edge-intelligence.md">ADR-039</a>, <a href="docs/adr/ADR-040-wasm-programmable-sensing.md">ADR-040</a>)</td>
<td><code>v0.3.0-alpha-esp32</code></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/RuView/releases/tag/v0.2.0-esp32">v0.2.0</a></td>
<td>Raw CSI streaming, multi-node TDM, channel hopping</td>
<td><code>v0.2.0-esp32</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# 1. Flash the firmware to your ESP32-S3
python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  write_flash --flash-mode dio --flash-size 8MB --flash-freq 80m \
  0x0 bootloader.bin 0x8000 partition-table.bin \
  0xf000 ota_data_initial.bin 0x20000 esp32-csi-node.bin

# 2. Set WiFi credentials and server address (stored in flash, survives reboots)
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid &quot;YourWiFi&quot; --password &quot;secret&quot; --target-ip 192.168.1.20

# 3. (Optional) Start the host server to visualize data
cargo run -p wifi-densepose-sensing-server -- --http-port 3000 --source auto
# Open http://localhost:3000"><pre><span class="pl-c"><span class="pl-c">#</span> 1. Flash the firmware to your ESP32-S3</span>
python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  write_flash --flash-mode dio --flash-size 8MB --flash-freq 80m \
  0x0 bootloader.bin 0x8000 partition-table.bin \
  0xf000 ota_data_initial.bin 0x20000 esp32-csi-node.bin

<span class="pl-c"><span class="pl-c">#</span> 2. Set WiFi credentials and server address (stored in flash, survives reboots)</span>
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid <span class="pl-s"><span class="pl-pds">"</span>YourWiFi<span class="pl-pds">"</span></span> --password <span class="pl-s"><span class="pl-pds">"</span>secret<span class="pl-pds">"</span></span> --target-ip 192.168.1.20

<span class="pl-c"><span class="pl-c">#</span> 3. (Optional) Start the host server to visualize data</span>
cargo run -p wifi-densepose-sensing-server -- --http-port 3000 --source auto
<span class="pl-c"><span class="pl-c">#</span> Open http://localhost:3000</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Multi-node mesh</h3><a id="user-content-multi-node-mesh" class="anchor" aria-label="Permalink: Multi-node mesh" href="#multi-node-mesh"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">For better accuracy and room coverage, deploy 3-6 nodes with time-division multiplexing (TDM) so they take turns transmitting:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Node 0 of a 3-node mesh
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid &quot;YourWiFi&quot; --password &quot;secret&quot; --target-ip 192.168.1.20 \
  --node-id 0 --tdm-slot 0 --tdm-total 3

# Node 1
python firmware/esp32-csi-node/provision.py --port COM8 \
  --ssid &quot;YourWiFi&quot; --password &quot;secret&quot; --target-ip 192.168.1.20 \
  --node-id 1 --tdm-slot 1 --tdm-total 3"><pre><span class="pl-c"><span class="pl-c">#</span> Node 0 of a 3-node mesh</span>
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid <span class="pl-s"><span class="pl-pds">"</span>YourWiFi<span class="pl-pds">"</span></span> --password <span class="pl-s"><span class="pl-pds">"</span>secret<span class="pl-pds">"</span></span> --target-ip 192.168.1.20 \
  --node-id 0 --tdm-slot 0 --tdm-total 3

<span class="pl-c"><span class="pl-c">#</span> Node 1</span>
python firmware/esp32-csi-node/provision.py --port COM8 \
  --ssid <span class="pl-s"><span class="pl-pds">"</span>YourWiFi<span class="pl-pds">"</span></span> --password <span class="pl-s"><span class="pl-pds">"</span>secret<span class="pl-pds">"</span></span> --target-ip 192.168.1.20 \
  --node-id 1 --tdm-slot 1 --tdm-total 3</pre></div>
<p dir="auto">Nodes can also hop across WiFi channels (1, 6, 11) to increase sensing bandwidth — configured via <a href="docs/adr/ADR-029-ruvsense-multistatic-sensing-mode.md">ADR-029</a> channel hopping.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">On-device intelligence (v0.3.0-alpha)</h3><a id="user-content-on-device-intelligence-v030-alpha" class="anchor" aria-label="Permalink: On-device intelligence (v0.3.0-alpha)" href="#on-device-intelligence-v030-alpha"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The alpha firmware can analyze signals locally and send compact results instead of raw data. This means the ESP32 works standalone — no server needed for basic sensing. Disabled by default for backward compatibility.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Tier</th>
<th>What it does</th>
<th>RAM used</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>0</strong></td>
<td>Off — streams raw CSI only (same as v0.2.0)</td>
<td>0 KB</td>
</tr>
<tr>
<td><strong>1</strong></td>
<td>Cleans up signals, picks the best subcarriers, compresses data (saves 30-50% bandwidth)</td>
<td>~30 KB</td>
</tr>
<tr>
<td><strong>2</strong></td>
<td>Everything in Tier 1 + detects presence, measures breathing and heart rate, detects falls</td>
<td>~33 KB</td>
</tr>
<tr>
<td><strong>3</strong></td>
<td>Everything in Tier 2 + runs custom WASM modules (gesture recognition, intrusion detection, and <a href="docs/edge-modules/README.md">63 more</a>)</td>
<td>~160 KB/module</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">Enable without reflashing — just reprovision:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Turn on Tier 2 (vitals) on an already-flashed node
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid &quot;YourWiFi&quot; --password &quot;secret&quot; --target-ip 192.168.1.20 \
  --edge-tier 2

# Fine-tune detection thresholds
python firmware/esp32-csi-node/provision.py --port COM7 \
  --edge-tier 2 --vital-int 500 --fall-thresh 5000 --subk-count 16"><pre><span class="pl-c"><span class="pl-c">#</span> Turn on Tier 2 (vitals) on an already-flashed node</span>
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid <span class="pl-s"><span class="pl-pds">"</span>YourWiFi<span class="pl-pds">"</span></span> --password <span class="pl-s"><span class="pl-pds">"</span>secret<span class="pl-pds">"</span></span> --target-ip 192.168.1.20 \
  --edge-tier 2

<span class="pl-c"><span class="pl-c">#</span> Fine-tune detection thresholds</span>
python firmware/esp32-csi-node/provision.py --port COM7 \
  --edge-tier 2 --vital-int 500 --fall-thresh 5000 --subk-count 16</pre></div>
<p dir="auto">When Tier 2 is active, the node sends a 32-byte vitals packet once per second containing: presence, motion level, breathing BPM, heart rate BPM, confidence scores, fall alert flag, and occupancy count.</p>
<p dir="auto">See <a href="firmware/esp32-csi-node/README.md">firmware/esp32-csi-node/README.md</a>, <a href="docs/adr/ADR-039-esp32-edge-intelligence.md">ADR-039</a>, <a href="docs/adr/ADR-044-provisioning-tool-enhancements.md">ADR-044</a>, and <a href="https://github.com/ruvnet/RuView/issues/34" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/34/hovercard">Tutorial #34</a>.</p>
</details>
<details>
<summary><strong>🦀 Rust Implementation (v2)</strong> — 810x faster, 54K fps pipeline</summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Performance Benchmarks (Validated)</h3><a id="user-content-performance-benchmarks-validated" class="anchor" aria-label="Permalink: Performance Benchmarks (Validated)" href="#performance-benchmarks-validated"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Operation</th>
<th>Python (v1)</th>
<th>Rust (v2)</th>
<th>Speedup</th>
</tr>
</thead>
<tbody>
<tr>
<td>CSI Preprocessing (4x64)</td>
<td>~5ms</td>
<td><strong>5.19 µs</strong></td>
<td>~1000x</td>
</tr>
<tr>
<td>Phase Sanitization (4x64)</td>
<td>~3ms</td>
<td><strong>3.84 µs</strong></td>
<td>~780x</td>
</tr>
<tr>
<td>Feature Extraction (4x64)</td>
<td>~8ms</td>
<td><strong>9.03 µs</strong></td>
<td>~890x</td>
</tr>
<tr>
<td>Motion Detection</td>
<td>~1ms</td>
<td><strong>186 ns</strong></td>
<td>~5400x</td>
</tr>
<tr>
<td><strong>Full Pipeline</strong></td>
<td>~15ms</td>
<td><strong>18.47 µs</strong></td>
<td>~810x</td>
</tr>
<tr>
<td><strong>Vital Signs</strong></td>
<td>N/A</td>
<td><strong>86 µs</strong></td>
<td>11,665 fps</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Resource</th>
<th>Python (v1)</th>
<th>Rust (v2)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Memory</td>
<td>~500 MB</td>
<td>~100 MB</td>
</tr>
<tr>
<td>Docker Image</td>
<td>569 MB</td>
<td>132 MB</td>
</tr>
<tr>
<td>Tests</td>
<td>41</td>
<td>542+</td>
</tr>
<tr>
<td>WASM Support</td>
<td>No</td>
<td>Yes</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd rust-port/wifi-densepose-rs
cargo build --release
cargo test --workspace
cargo bench --package wifi-densepose-signal"><pre><span class="pl-c1">cd</span> rust-port/wifi-densepose-rs
cargo build --release
cargo <span class="pl-c1">test</span> --workspace
cargo bench --package wifi-densepose-signal</pre></div>
</details>
<details>
<summary><a id="user-content-vital-sign-detection"></a><strong>💓 Vital Sign Detection (ADR-021)</strong> — Breathing and heartbeat via FFT</summary>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Capability</th>
<th>Range</th>
<th>Method</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Breathing Rate</strong></td>
<td>6-30 BPM (0.1-0.5 Hz)</td>
<td>Bandpass filter + FFT peak detection</td>
</tr>
<tr>
<td><strong>Heart Rate</strong></td>
<td>40-120 BPM (0.8-2.0 Hz)</td>
<td>Bandpass filter + FFT peak detection</td>
</tr>
<tr>
<td><strong>Sampling Rate</strong></td>
<td>20 Hz (ESP32 CSI)</td>
<td>Real-time streaming</td>
</tr>
<tr>
<td><strong>Confidence</strong></td>
<td>0.0-1.0 per sign</td>
<td>Spectral coherence + signal quality</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./target/release/sensing-server --source simulate --http-port 3000 --ws-port 3001 --ui-path ../../ui
curl http://localhost:3000/api/v1/vital-signs"><pre>./target/release/sensing-server --source simulate --http-port 3000 --ws-port 3001 --ui-path ../../ui
curl http://localhost:3000/api/v1/vital-signs</pre></div>
<p dir="auto">See <a href="docs/adr/ADR-021-vital-sign-detection-rvdna-pipeline.md">ADR-021</a>.</p>
</details>
<details>
<summary><a id="user-content-wifi-scan-domain-layer"></a><strong>📡 WiFi Scan Domain Layer (ADR-022/025)</strong> — 8-stage RSSI pipeline for Windows, macOS, and Linux WiFi</summary>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Stage</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Predictive Gating</strong></td>
<td>Pre-filter scan results using temporal prediction</td>
</tr>
<tr>
<td><strong>Attention Weighting</strong></td>
<td>Weight BSSIDs by signal relevance</td>
</tr>
<tr>
<td><strong>Spatial Correlation</strong></td>
<td>Cross-AP spatial signal correlation</td>
</tr>
<tr>
<td><strong>Motion Estimation</strong></td>
<td>Detect movement from RSSI variance</td>
</tr>
<tr>
<td><strong>Breathing Extraction</strong></td>
<td>Extract respiratory rate from sub-Hz oscillations</td>
</tr>
<tr>
<td><strong>Quality Gating</strong></td>
<td>Reject low-confidence estimates</td>
</tr>
<tr>
<td><strong>Fingerprint Matching</strong></td>
<td>Location and posture classification via RF fingerprints</td>
</tr>
<tr>
<td><strong>Orchestration</strong></td>
<td>Fuse all stages into unified sensing output</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cargo test -p wifi-densepose-wifiscan"><pre>cargo <span class="pl-c1">test</span> -p wifi-densepose-wifiscan</pre></div>
<p dir="auto">See <a href="docs/adr/ADR-022-windows-wifi-enhanced-fidelity-ruvector.md">ADR-022</a> and <a href="https://github.com/ruvnet/RuView/issues/36" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/36/hovercard">Tutorial #36</a>.</p>
</details>
<details>
<summary><a id="user-content-wifi-mat-disaster-response"></a><strong>🚨 WiFi-Mat: Disaster Response</strong> — Search &amp; rescue, START triage, 3D localization</summary>
<p dir="auto">WiFi signals penetrate non-metallic debris (concrete, wood, drywall) where cameras and thermal sensors cannot reach. The WiFi-Mat module (<code>wifi-densepose-mat</code>, 139 tests) uses CSI analysis to detect survivors trapped under rubble, classify their condition using the START triage protocol, and estimate their 3D position — giving rescue teams actionable intelligence within seconds of deployment.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Capability</th>
<th>How It Works</th>
<th>Performance Target</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Breathing Detection</strong></td>
<td>Bandpass 0.07-1.0 Hz + Fresnel zone modeling detects chest displacement of 5-10mm at 5 GHz</td>
<td>4-60 BPM, &lt;500ms latency</td>
</tr>
<tr>
<td><strong>Heartbeat Detection</strong></td>
<td>Micro-Doppler shift extraction from fine-grained CSI phase variation</td>
<td>Via ruvector-temporal-tensor</td>
</tr>
<tr>
<td><strong>3D Localization</strong></td>
<td>Multi-AP triangulation + CSI fingerprint matching + depth estimation through rubble layers</td>
<td>3-5m penetration</td>
</tr>
<tr>
<td><strong>START Triage</strong></td>
<td>Ensemble classifier votes on breathing + movement + vital stability → P1-P4 priority</td>
<td>&lt;1% false negative</td>
</tr>
<tr>
<td><strong>Zone Scanning</strong></td>
<td>16+ concurrent scan zones with periodic re-scan and audit logging</td>
<td>Full disaster site</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Triage classification (START protocol compatible):</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Status</th>
<th>Color</th>
<th>Detection Criteria</th>
<th>Priority</th>
</tr>
</thead>
<tbody>
<tr>
<td>Immediate</td>
<td>Red</td>
<td>Breathing detected, no movement</td>
<td>P1</td>
</tr>
<tr>
<td>Delayed</td>
<td>Yellow</td>
<td>Movement + breathing, stable vitals</td>
<td>P2</td>
</tr>
<tr>
<td>Minor</td>
<td>Green</td>
<td>Strong movement, responsive patterns</td>
<td>P3</td>
</tr>
<tr>
<td>Deceased</td>
<td>Black</td>
<td>No vitals for &gt;30 min continuous scan</td>
<td>P4</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Deployment modes:</strong> portable (single TX/RX handheld), distributed (multiple APs around collapse site), drone-mounted (UAV scanning), vehicle-mounted (mobile command post).</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="use wifi_densepose_mat::{DisasterResponse, DisasterConfig, DisasterType, ScanZone, ZoneBounds};

let config = DisasterConfig::builder()
    .disaster_type(DisasterType::Earthquake)
    .sensitivity(0.85)
    .max_depth(5.0)
    .build();

let mut response = DisasterResponse::new(config);
response.initialize_event(location, &quot;Building collapse&quot;)?;
response.add_zone(ScanZone::new(&quot;North Wing&quot;, ZoneBounds::rectangle(0.0, 0.0, 30.0, 20.0)))?;
response.start_scanning().await?;"><pre><span class="pl-k">use</span> wifi_densepose_mat<span class="pl-kos">::</span><span class="pl-kos">{</span><span class="pl-v">DisasterResponse</span><span class="pl-kos">,</span> <span class="pl-v">DisasterConfig</span><span class="pl-kos">,</span> <span class="pl-v">DisasterType</span><span class="pl-kos">,</span> <span class="pl-v">ScanZone</span><span class="pl-kos">,</span> <span class="pl-v">ZoneBounds</span><span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> config = <span class="pl-smi">DisasterConfig</span><span class="pl-kos">::</span><span class="pl-en">builder</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
    <span class="pl-kos">.</span><span class="pl-en">disaster_type</span><span class="pl-kos">(</span><span class="pl-smi">DisasterType</span><span class="pl-kos">::</span><span class="pl-v">Earthquake</span><span class="pl-kos">)</span>
    <span class="pl-kos">.</span><span class="pl-en">sensitivity</span><span class="pl-kos">(</span><span class="pl-c1">0.85</span><span class="pl-kos">)</span>
    <span class="pl-kos">.</span><span class="pl-en">max_depth</span><span class="pl-kos">(</span><span class="pl-c1">5.0</span><span class="pl-kos">)</span>
    <span class="pl-kos">.</span><span class="pl-en">build</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">let</span> <span class="pl-k">mut</span> response = <span class="pl-smi">DisasterResponse</span><span class="pl-kos">::</span><span class="pl-en">new</span><span class="pl-kos">(</span>config<span class="pl-kos">)</span><span class="pl-kos">;</span>
response<span class="pl-kos">.</span><span class="pl-en">initialize_event</span><span class="pl-kos">(</span>location<span class="pl-kos">,</span> <span class="pl-s">"Building collapse"</span><span class="pl-kos">)</span>?<span class="pl-kos">;</span>
response<span class="pl-kos">.</span><span class="pl-en">add_zone</span><span class="pl-kos">(</span><span class="pl-smi">ScanZone</span><span class="pl-kos">::</span><span class="pl-en">new</span><span class="pl-kos">(</span><span class="pl-s">"North Wing"</span><span class="pl-kos">,</span> <span class="pl-smi">ZoneBounds</span><span class="pl-kos">::</span><span class="pl-en">rectangle</span><span class="pl-kos">(</span><span class="pl-c1">0.0</span><span class="pl-kos">,</span> <span class="pl-c1">0.0</span><span class="pl-kos">,</span> <span class="pl-c1">30.0</span><span class="pl-kos">,</span> <span class="pl-c1">20.0</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span>?<span class="pl-kos">;</span>
response<span class="pl-kos">.</span><span class="pl-en">start_scanning</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-k">await</span>?<span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Safety guarantees:</strong> fail-safe defaults (assume life present on ambiguous signals), redundant multi-algorithm voting, complete audit trail, offline-capable (no network required).</p>
<ul dir="auto">
<li><a href="docs/wifi-mat-user-guide.md">WiFi-Mat User Guide</a> | <a href="docs/adr/ADR-001-wifi-mat-disaster-detection.md">ADR-001</a> | <a href="docs/ddd/wifi-mat-domain-model.md">Domain Model</a></li>
</ul>
</details>
<details>
<summary><a id="user-content-sota-signal-processing"></a><strong>🔬 SOTA Signal Processing (ADR-014)</strong> — 6 research-grade algorithms</summary>
<p dir="auto">The signal processing layer bridges the gap between raw commodity WiFi hardware output and research-grade sensing accuracy. Each algorithm addresses a specific limitation of naive CSI processing — from hardware-induced phase corruption to environment-dependent multipath interference. All six are implemented in <code>wifi-densepose-signal/src/</code> with deterministic tests and no mock data.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Algorithm</th>
<th>What It Does</th>
<th>Why It Matters</th>
<th>Math</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Conjugate Multiplication</strong></td>
<td>Multiplies CSI antenna pairs: <code>H₁[k] × conj(H₂[k])</code></td>
<td>Cancels CFO, SFO, and packet detection delay that corrupt raw phase — preserves only environment-caused phase differences</td>
<td><code>CSI_ratio[k] = H₁[k] * conj(H₂[k])</code></td>
<td><a href="https://dl.acm.org/doi/10.1145/2789168.2790124" rel="nofollow">SpotFi</a> (SIGCOMM 2015)</td>
</tr>
<tr>
<td><strong>Hampel Filter</strong></td>
<td>Replaces outliers using running median ± scaled MAD</td>
<td>Z-score uses mean/std which are corrupted by the very outliers it detects (masking effect). Hampel uses median/MAD, resisting up to 50% contamination</td>
<td><code>σ̂ = 1.4826 × MAD</code></td>
<td>Standard DSP; WiGest (2015)</td>
</tr>
<tr>
<td><strong>Fresnel Zone Model</strong></td>
<td>Models signal variation from chest displacement crossing Fresnel zone boundaries</td>
<td>Zero-crossing counting fails in multipath-rich environments. Fresnel predicts <em>where</em> breathing should appear based on TX-RX-body geometry</td>
<td><code>ΔΦ = 2π × 2Δd / λ</code>, <code>A = |sin(ΔΦ/2)|</code></td>
<td><a href="https://dl.acm.org/doi/10.1145/3300061.3345431" rel="nofollow">FarSense</a> (MobiCom 2019)</td>
</tr>
<tr>
<td><strong>CSI Spectrogram</strong></td>
<td>Sliding-window FFT (STFT) per subcarrier → 2D time-frequency matrix</td>
<td>Breathing = 0.2-0.4 Hz band, walking = 1-2 Hz, static = noise. 2D structure enables CNN spatial pattern recognition that 1D features miss</td>
<td><code>S[t,f] = |Σₙ x[n] w[n-t] e^{-j2πfn}|²</code></td>
<td>Standard since 2018</td>
</tr>
<tr>
<td><strong>Subcarrier Selection</strong></td>
<td>Ranks subcarriers by motion sensitivity (variance ratio) and selects top-K</td>
<td>Not all subcarriers respond to motion — some sit in multipath nulls. Selecting the 10-20 most sensitive improves SNR by 6-10 dB</td>
<td><code>sensitivity[k] = var_motion / var_static</code></td>
<td><a href="https://dl.acm.org/doi/10.1145/3117811.3117826" rel="nofollow">WiDance</a> (MobiCom 2017)</td>
</tr>
<tr>
<td><strong>Body Velocity Profile</strong></td>
<td>Extracts velocity distribution from Doppler shifts across subcarriers</td>
<td>BVP is domain-independent — same velocity profile regardless of room layout, furniture, or AP placement. Basis for cross-environment recognition</td>
<td><code>BVP[v,t] = Σₖ |STFTₖ[v,t]|</code></td>
<td><a href="https://dl.acm.org/doi/10.1145/3328916" rel="nofollow">Widar 3.0</a> (MobiSys 2019)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Processing pipeline order:</strong> Raw CSI → Conjugate multiplication (phase cleaning) → Hampel filter (outlier removal) → Subcarrier selection (top-K) → CSI spectrogram (time-frequency) → Fresnel model (breathing) + BVP (activity)</p>
<p dir="auto">See <a href="docs/adr/ADR-014-sota-signal-processing.md">ADR-014</a> for full mathematical derivations.</p>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🧠 Models &amp; Training</h2><a id="user-content--models--training" class="anchor" aria-label="Permalink: 🧠 Models &amp; Training" href="#-models--training"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><a id="user-content-ai-backbone-ruvector"></a><strong>🤖 AI Backbone: RuVector</strong> — Attention, graph algorithms, and edge-AI compression powering the sensing pipeline</summary>
<p dir="auto">Raw WiFi signals are noisy, redundant, and environment-dependent. <a href="https://github.com/ruvnet/ruvector">RuVector</a> is the AI intelligence layer that transforms them into clean, structured input for the DensePose neural network. It uses <strong>attention mechanisms</strong> to learn which signals to trust, <strong>graph algorithms</strong> that automatically discover which WiFi channels are sensitive to body motion, and <strong>compressed representations</strong> that make edge inference possible on an $8 microcontroller.</p>
<p dir="auto">Without RuVector, WiFi DensePose would need hand-tuned thresholds, brute-force matrix math, and 4x more memory — making real-time edge inference impossible.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Raw WiFi CSI (56 subcarriers, noisy)
    |
    +-- ruvector-mincut ---------- Which channels carry body-motion signal? (learned graph partitioning)
    +-- ruvector-attn-mincut ----- Which time frames are signal vs noise? (attention-gated filtering)
    +-- ruvector-attention ------- How to fuse multi-antenna data? (learned weighted aggregation)
    |
    v
Clean, structured signal --&gt; DensePose Neural Network --&gt; 17-keypoint body pose
                         --&gt; FFT Vital Signs -----------&gt; breathing rate, heart rate
                         --&gt; ruvector-solver ------------&gt; physics-based localization"><pre class="notranslate"><code>Raw WiFi CSI (56 subcarriers, noisy)
    |
    +-- ruvector-mincut ---------- Which channels carry body-motion signal? (learned graph partitioning)
    +-- ruvector-attn-mincut ----- Which time frames are signal vs noise? (attention-gated filtering)
    +-- ruvector-attention ------- How to fuse multi-antenna data? (learned weighted aggregation)
    |
    v
Clean, structured signal --&gt; DensePose Neural Network --&gt; 17-keypoint body pose
                         --&gt; FFT Vital Signs -----------&gt; breathing rate, heart rate
                         --&gt; ruvector-solver ------------&gt; physics-based localization
</code></pre></div>
<p dir="auto">The <a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow"><code>wifi-densepose-ruvector</code></a> crate (<a href="docs/adr/ADR-017-ruvector-signal-mat-integration.md">ADR-017</a>) connects all 7 integration points:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>AI Capability</th>
<th>What It Replaces</th>
<th>RuVector Crate</th>
<th>Result</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Self-optimizing channel selection</strong></td>
<td>Hand-tuned thresholds that break when rooms change</td>
<td><code>ruvector-mincut</code></td>
<td>Graph min-cut adapts to any environment automatically</td>
</tr>
<tr>
<td><strong>Attention-based signal cleaning</strong></td>
<td>Fixed energy cutoffs that miss subtle breathing</td>
<td><code>ruvector-attn-mincut</code></td>
<td>Learned gating amplifies body signals, suppresses noise</td>
</tr>
<tr>
<td><strong>Learned signal fusion</strong></td>
<td>Simple averaging where one bad channel corrupts all</td>
<td><code>ruvector-attention</code></td>
<td>Transformer-style attention downweights corrupted channels</td>
</tr>
<tr>
<td><strong>Physics-informed localization</strong></td>
<td>Expensive nonlinear solvers</td>
<td><code>ruvector-solver</code></td>
<td>Sparse least-squares Fresnel geometry in real-time</td>
</tr>
<tr>
<td><strong>O(1) survivor triangulation</strong></td>
<td>O(N^3) matrix inversion</td>
<td><code>ruvector-solver</code></td>
<td>Neumann series linearization for instant position updates</td>
</tr>
<tr>
<td><strong>75% memory compression</strong></td>
<td>13.4 MB breathing buffers that overflow edge devices</td>
<td><code>ruvector-temporal-tensor</code></td>
<td>Tiered 3-8 bit quantization fits 60s of vitals in 3.4 MB</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">See <a href="https://github.com/ruvnet/RuView/issues/67" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/67/hovercard">issue #67</a> for a deep dive with code examples, or <a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow"><code>cargo add wifi-densepose-ruvector</code></a> to use it directly.</p>
</details>
<details>
<summary><a id="user-content-rvf-model-container"></a><strong>📦 RVF Model Container</strong> — Single-file deployment with progressive loading</summary>
<p dir="auto">The <a href="https://github.com/ruvnet/ruvector/tree/main/crates/rvf">RuVector Format (RVF)</a> packages an entire trained model — weights, HNSW indexes, quantization codebooks, SONA adaptation deltas, and WASM inference runtime — into a single self-contained binary file. No external dependencies are needed at deployment time.</p>
<p dir="auto"><strong>Container structure:</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="┌──────────────────────────────────────────────────────┐
│ RVF Container (.rvf)                                  │
│                                                       │
│  ┌─────────────┐  64-byte header per segment          │
│  │ Manifest     │  Magic: 0x52564653 (&quot;RVFS&quot;)         │
│  ├─────────────┤  Type + content hash + compression   │
│  │ Weights      │  Model parameters (f32/f16/u8)      │
│  ├─────────────┤                                      │
│  │ HNSW Index   │  Vector search index                │
│  ├─────────────┤                                      │
│  │ Quant        │  Quantization codebooks              │
│  ├─────────────┤                                      │
│  │ SONA Profile │  LoRA deltas + EWC++ Fisher matrix  │
│  ├─────────────┤                                      │
│  │ Witness      │  Ed25519 training proof              │
│  ├─────────────┤                                      │
│  │ Vitals Config│  Breathing/HR filter parameters     │
│  └─────────────┘                                      │
└──────────────────────────────────────────────────────┘"><pre class="notranslate"><code>┌──────────────────────────────────────────────────────┐
│ RVF Container (.rvf)                                  │
│                                                       │
│  ┌─────────────┐  64-byte header per segment          │
│  │ Manifest     │  Magic: 0x52564653 ("RVFS")         │
│  ├─────────────┤  Type + content hash + compression   │
│  │ Weights      │  Model parameters (f32/f16/u8)      │
│  ├─────────────┤                                      │
│  │ HNSW Index   │  Vector search index                │
│  ├─────────────┤                                      │
│  │ Quant        │  Quantization codebooks              │
│  ├─────────────┤                                      │
│  │ SONA Profile │  LoRA deltas + EWC++ Fisher matrix  │
│  ├─────────────┤                                      │
│  │ Witness      │  Ed25519 training proof              │
│  ├─────────────┤                                      │
│  │ Vitals Config│  Breathing/HR filter parameters     │
│  └─────────────┘                                      │
└──────────────────────────────────────────────────────┘
</code></pre></div>
<p dir="auto"><strong>Deployment targets:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Target</th>
<th>Quantization</th>
<th>Size</th>
<th>Load Time</th>
<th>Use Case</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ESP32 / IoT</strong></td>
<td>int4</td>
<td>~0.7 MB</td>
<td>&lt;5ms (Layer A)</td>
<td>Presence + breathing only</td>
</tr>
<tr>
<td><strong>Mobile / WebView</strong></td>
<td>int8</td>
<td>~6 MB</td>
<td>~200ms (Layer B)</td>
<td>Pose estimation on phone</td>
</tr>
<tr>
<td><strong>Browser (WASM)</strong></td>
<td>int8</td>
<td>~10 MB</td>
<td>~500ms (Layer B)</td>
<td>In-browser demo</td>
</tr>
<tr>
<td><strong>Field (WiFi-Mat)</strong></td>
<td>fp16</td>
<td>~62 MB</td>
<td>~2s (Layer C)</td>
<td>Full DensePose + disaster triage</td>
</tr>
<tr>
<td><strong>Server / Cloud</strong></td>
<td>f32</td>
<td>~50+ MB</td>
<td>~3s (Layer C)</td>
<td>Training + full inference</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Property</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Format</strong></td>
<td>Segment-based binary, 20+ segment types, CRC32 integrity per segment</td>
</tr>
<tr>
<td><strong>Progressive Loading</strong></td>
<td><strong>Layer A</strong> (&lt;5ms): manifest + entry points → <strong>Layer B</strong> (100ms-1s): hot weights + adjacency → <strong>Layer C</strong> (seconds): full graph</td>
</tr>
<tr>
<td><strong>Signing</strong></td>
<td>Ed25519 training proofs for verifiable provenance — chain of custody from training data to deployed model</td>
</tr>
<tr>
<td><strong>Quantization</strong></td>
<td>Per-segment temperature-tiered: f32 (full), f16 (half), u8 (int8), int4 — with SIMD-accelerated distance computation</td>
</tr>
<tr>
<td><strong>CLI</strong></td>
<td><code>--export-rvf</code> (generate), <code>--load-rvf</code> (config), <code>--save-rvf</code> (persist), <code>--model</code> (inference), <code>--progressive</code> (3-layer load)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Export model package
./target/release/sensing-server --export-rvf wifi-densepose-v1.rvf

# Load and run with progressive loading
./target/release/sensing-server --model wifi-densepose-v1.rvf --progressive

# Export via Docker
docker run --rm -v $(pwd):/out ruvnet/wifi-densepose:latest --export-rvf /out/model.rvf"><pre><span class="pl-c"><span class="pl-c">#</span> Export model package</span>
./target/release/sensing-server --export-rvf wifi-densepose-v1.rvf

<span class="pl-c"><span class="pl-c">#</span> Load and run with progressive loading</span>
./target/release/sensing-server --model wifi-densepose-v1.rvf --progressive

<span class="pl-c"><span class="pl-c">#</span> Export via Docker</span>
docker run --rm -v <span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>:/out ruvnet/wifi-densepose:latest --export-rvf /out/model.rvf</pre></div>
<p dir="auto">Built on the <a href="https://github.com/ruvnet/ruvector/tree/main/crates/rvf">rvf</a> crate family (rvf-types, rvf-wire, rvf-manifest, rvf-index, rvf-quant, rvf-crypto, rvf-runtime). See <a href="docs/adr/ADR-023-trained-densepose-model-ruvector-pipeline.md">ADR-023</a>.</p>
</details>
<details>
<summary><a id="user-content-training--fine-tuning"></a><strong>🧬 Training &amp; Fine-Tuning</strong> — MM-Fi/Wi-Pose pre-training, SONA adaptation</summary>
<p dir="auto">The training pipeline implements 8 phases in pure Rust (7,832 lines, zero external ML dependencies). It trains a graph transformer with cross-attention to map CSI feature matrices to 17 COCO body keypoints and DensePose UV coordinates — following the approach from the CMU "DensePose From WiFi" paper (<a href="https://arxiv.org/abs/2301.00250" rel="nofollow">arXiv:2301.00250</a>). RuVector crates provide the core building blocks: <a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-attention">ruvector-attention</a> for cross-attention layers, <a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-mincut">ruvector-mincut</a> for multi-person matching, and <a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-temporal-tensor">ruvector-temporal-tensor</a> for CSI buffer compression.</p>
<p dir="auto"><strong>Three-tier data strategy:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Tier</th>
<th>Method</th>
<th>Purpose</th>
<th>RuVector Integration</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>1. Pre-train</strong></td>
<td>MM-Fi + Wi-Pose public datasets</td>
<td>Cross-environment generalization (multi-subject, multi-room)</td>
<td><code>ruvector-temporal-tensor</code> compresses CSI windows (114→56 subcarrier resampling)</td>
</tr>
<tr>
<td><strong>2. Fine-tune</strong></td>
<td>ESP32 CSI + camera pseudo-labels</td>
<td>Environment-specific multipath adaptation</td>
<td><code>ruvector-solver</code> for Fresnel geometry, <code>ruvector-attn-mincut</code> for subcarrier gating</td>
</tr>
<tr>
<td><strong>3. SONA adapt</strong></td>
<td>Micro-LoRA (rank-4) + EWC++</td>
<td>Continuous on-device learning without catastrophic forgetting</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/sona">SONA</a> architecture (Self-Optimizing Neural Architecture)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>Training pipeline components:</strong></p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Phase</th>
<th>Module</th>
<th>What It Does</th>
<th>RuVector Crate</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><code>dataset.rs</code> (850 lines)</td>
<td>MM-Fi <code>.npy</code> + Wi-Pose <code>.mat</code> loaders, subcarrier resampling (114→56, 30→56), windowing</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-temporal-tensor">ruvector-temporal-tensor</a></td>
</tr>
<tr>
<td>2</td>
<td><code>graph_transformer.rs</code> (855 lines)</td>
<td>COCO BodyGraph (17 kp, 16 edges), AntennaGraph, multi-head CrossAttention, GCN message passing</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-attention">ruvector-attention</a></td>
</tr>
<tr>
<td>3</td>
<td><code>trainer.rs</code> (881 lines)</td>
<td>6-term composite loss (MSE, CE, UV, temporal, bone, symmetry), SGD+momentum, cosine+warmup, PCK/OKS</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-mincut">ruvector-mincut</a> (person matching)</td>
</tr>
<tr>
<td>4</td>
<td><code>sona.rs</code> (639 lines)</td>
<td>LoRA adapters (A×B delta), EWC++ Fisher regularization, EnvironmentDetector (3-sigma drift)</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/sona">sona</a></td>
</tr>
<tr>
<td>5</td>
<td><code>sparse_inference.rs</code> (753 lines)</td>
<td>NeuronProfiler hot/cold partitioning, SparseLinear (skip cold rows), INT8/FP16 quantization</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-sparse-inference">ruvector-sparse-inference</a></td>
</tr>
<tr>
<td>6</td>
<td><code>rvf_pipeline.rs</code> (1,027 lines)</td>
<td>Progressive 3-layer loader, HNSW index, OverlayGraph, <code>RvfModelBuilder</code></td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-core">ruvector-core</a> (HNSW)</td>
</tr>
<tr>
<td>7</td>
<td><code>rvf_container.rs</code> (914 lines)</td>
<td>Binary container format, 6+ segment types, CRC32 integrity</td>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/rvf">rvf</a></td>
</tr>
<tr>
<td>8</td>
<td><code>main.rs</code> integration</td>
<td><code>--train</code>, <code>--model</code>, <code>--progressive</code> CLI flags, REST endpoints</td>
<td>—</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>SONA (Self-Optimizing Neural Architecture)</strong> — the continuous adaptation system:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Component</th>
<th>What It Does</th>
<th>Why It Matters</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Micro-LoRA (rank-4)</strong></td>
<td>Trains small A×B weight deltas instead of full weights</td>
<td>100x fewer parameters to update → runs on ESP32</td>
</tr>
<tr>
<td><strong>EWC++ (Fisher matrix)</strong></td>
<td>Penalizes changes to important weights from previous environments</td>
<td>Prevents catastrophic forgetting when moving between rooms</td>
</tr>
<tr>
<td><strong>EnvironmentDetector</strong></td>
<td>Monitors CSI feature drift with 3-sigma threshold</td>
<td>Auto-triggers adaptation when the model is moved to a new space</td>
</tr>
<tr>
<td><strong>Best-epoch snapshot</strong></td>
<td>Saves best validation loss weights, restores before export</td>
<td>Prevents shipping overfit final-epoch parameters</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Pre-train on MM-Fi dataset
./target/release/sensing-server --train --dataset data/ --dataset-type mmfi --epochs 100

# Train and export to RVF in one step
./target/release/sensing-server --train --dataset data/ --epochs 100 --save-rvf model.rvf

# Via Docker (no toolchain needed)
docker run --rm -v $(pwd)/data:/data ruvnet/wifi-densepose:latest \
  --train --dataset /data --epochs 100 --export-rvf /data/model.rvf"><pre><span class="pl-c"><span class="pl-c">#</span> Pre-train on MM-Fi dataset</span>
./target/release/sensing-server --train --dataset data/ --dataset-type mmfi --epochs 100

<span class="pl-c"><span class="pl-c">#</span> Train and export to RVF in one step</span>
./target/release/sensing-server --train --dataset data/ --epochs 100 --save-rvf model.rvf

<span class="pl-c"><span class="pl-c">#</span> Via Docker (no toolchain needed)</span>
docker run --rm -v <span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/data:/data ruvnet/wifi-densepose:latest \
  --train --dataset /data --epochs 100 --export-rvf /data/model.rvf</pre></div>
<p dir="auto">See <a href="docs/adr/ADR-023-trained-densepose-model-ruvector-pipeline.md">ADR-023</a> · <a href="https://github.com/ruvnet/ruvector/tree/main/crates/sona">SONA crate</a> · <a href="https://arxiv.org/abs/2301.00250" rel="nofollow">arXiv:2301.00250</a></p>
</details>
<details>
<summary><a id="user-content-ruvector-crates"></a><strong>🔩 RuVector Crates</strong> — 11 vendored signal intelligence crates from <a href="https://github.com/ruvnet/ruvector">github.com/ruvnet/ruvector</a></summary>
<p dir="auto"><strong>5 directly-used crates</strong> (v2.0.4, declared in <code>Cargo.toml</code>, 7 integration points):</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Crate</th>
<th>What It Does</th>
<th>Where It's Used in WiFi-DensePose</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-attention"><code>ruvector-attention</code></a></td>
<td>Scaled dot-product attention, MoE routing, sparse attention</td>
<td><code>model.rs</code> (spatial attention), <code>bvp.rs</code> (sensitivity-weighted velocity profiles)</td>
<td><a href="https://crates.io/crates/ruvector-attention" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-mincut"><code>ruvector-mincut</code></a></td>
<td>Subpolynomial dynamic min-cut O(n^1.5 log n)</td>
<td><code>metrics.rs</code> (DynamicPersonMatcher — multi-person assignment), <code>subcarrier_selection.rs</code> (sensitive/insensitive split)</td>
<td><a href="https://crates.io/crates/ruvector-mincut" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-attn-mincut"><code>ruvector-attn-mincut</code></a></td>
<td>Attention-gated spectrogram noise suppression</td>
<td><code>model.rs</code> (antenna attention gating), <code>spectrogram.rs</code> (gate noisy time-frequency bins)</td>
<td><a href="https://crates.io/crates/ruvector-attn-mincut" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-solver"><code>ruvector-solver</code></a></td>
<td>Sparse Neumann series solver O(sqrt(n))</td>
<td><code>fresnel.rs</code> (TX-body-RX geometry), <code>triangulation.rs</code> (3D localization), <code>subcarrier.rs</code> (sparse interpolation 114→56)</td>
<td><a href="https://crates.io/crates/ruvector-solver" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-temporal-tensor"><code>ruvector-temporal-tensor</code></a></td>
<td>Tiered temporal compression (8/7/5/3-bit)</td>
<td><code>dataset.rs</code> (CSI buffer compression), <code>breathing.rs</code> + <code>heartbeat.rs</code> (compressed vital sign spectrograms)</td>
<td><a href="https://crates.io/crates/ruvector-temporal-tensor" rel="nofollow">crate</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>6 additional vendored crates</strong> (used by training pipeline and inference):</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Crate</th>
<th>What It Does</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-core"><code>ruvector-core</code></a></td>
<td>VectorDB engine, HNSW index, SIMD distance functions, quantization codebooks</td>
<td><a href="https://crates.io/crates/ruvector-core" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-gnn"><code>ruvector-gnn</code></a></td>
<td>Graph neural network layers, graph attention, EWC-regularized training</td>
<td><a href="https://crates.io/crates/ruvector-gnn" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-graph-transformer"><code>ruvector-graph-transformer</code></a></td>
<td>Proof-gated graph transformer with cross-attention</td>
<td><a href="https://crates.io/crates/ruvector-graph-transformer" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-sparse-inference"><code>ruvector-sparse-inference</code></a></td>
<td>PowerInfer-style hot/cold neuron partitioning, skip cold rows at runtime</td>
<td><a href="https://crates.io/crates/ruvector-sparse-inference" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-nervous-system"><code>ruvector-nervous-system</code></a></td>
<td>PredictiveLayer, OscillatoryRouter, Hopfield associative memory</td>
<td><a href="https://crates.io/crates/ruvector-nervous-system" rel="nofollow">crate</a></td>
</tr>
<tr>
<td><a href="https://github.com/ruvnet/ruvector/tree/main/crates/ruvector-coherence"><code>ruvector-coherence</code></a></td>
<td>Spectral coherence monitoring, HNSW graph health, Fiedler connectivity</td>
<td><a href="https://crates.io/crates/ruvector-coherence" rel="nofollow">crate</a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">The full RuVector ecosystem includes 90+ crates. See <a href="https://github.com/ruvnet/ruvector">github.com/ruvnet/ruvector</a> for the complete library, and <a href="vendor/ruvector/"><code>vendor/ruvector/</code></a> for the vendored source in this project.</p>
</details>
<details>
<summary><a id="user-content-ruv-neural"></a><strong>🧠 rUv Neural</strong> — Brain topology analysis ecosystem for neural decoding and medical sensing</summary>
<p dir="auto"><a href="rust-port/wifi-densepose-rs/crates/ruv-neural/README.md"><strong>rUv Neural</strong></a> is a 12-crate Rust ecosystem that extends RuView's signal processing into brain network topology analysis. It transforms neural magnetic field measurements from quantum sensors (NV diamond magnetometers, optically pumped magnetometers) into dynamic connectivity graphs, using minimum cut algorithms to detect cognitive state transitions in real time. The ecosystem includes crates for signal processing (<code>ruv-neural-signal</code>), graph construction (<code>ruv-neural-graph</code>), HNSW-indexed pattern memory (<code>ruv-neural-memory</code>), graph embeddings (<code>ruv-neural-embed</code>), cognitive state decoding (<code>ruv-neural-decoder</code>), and ESP32/WASM edge targets. Medical and research applications include early neurological disease detection via topology signatures, brain-computer interfaces, clinical neurofeedback, and non-invasive biomedical sensing -- bridging RuView's RF sensing architecture with the emerging field of quantum biomedical diagnostics.</p>
</details>
<hr>
<details>
<summary><strong>🏗️ System Architecture</strong> — End-to-end data flow from CSI capture to REST/WebSocket API</summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">End-to-End Pipeline</h3><a id="user-content-end-to-end-pipeline" class="anchor" aria-label="Permalink: End-to-End Pipeline" href="#end-to-end-pipeline"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<section class="js-render-needs-enrichment render-needs-enrichment position-relative" data-identity="360832ff-9655-486c-9269-8d4c3ccb9b41" data-host="https://viewscreen.githubusercontent.com" data-src="https://viewscreen.githubusercontent.com/markdown/mermaid?docs_host=https%3A%2F%2Fdocs.github.com" data-type="mermaid" aria-label="mermaid rendered output container">
  <div class="js-render-enrichment-target" data-json="{&quot;data&quot;:&quot;graph TB\n    subgraph HW [\&quot;📡 Hardware Layer\&quot;]\n        direction LR\n        R1[\&quot;WiFi Router 1&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;CSI Source&amp;lt;/small&amp;gt;\&quot;]\n        R2[\&quot;WiFi Router 2&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;CSI Source&amp;lt;/small&amp;gt;\&quot;]\n        R3[\&quot;WiFi Router 3&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;CSI Source&amp;lt;/small&amp;gt;\&quot;]\n        ESP[\&quot;ESP32-S3 Mesh&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;20 Hz · 56 subcarriers&amp;lt;/small&amp;gt;\&quot;]\n        WIN[\&quot;Windows WiFi&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;RSSI scanning&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph INGEST [\&quot;⚡ Ingestion\&quot;]\n        AGG[\&quot;Aggregator&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;UDP :5005 · ADR-018 frames&amp;lt;/small&amp;gt;\&quot;]\n        BRIDGE[\&quot;Bridge&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;I/Q → amplitude + phase&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph SIGNAL [\&quot;🔬 Signal Processing — RuVector v2.0.4\&quot;]\n        direction TB\n        PHASE[\&quot;Phase Sanitization&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;SpotFi conjugate multiply&amp;lt;/small&amp;gt;\&quot;]\n        HAMPEL[\&quot;Hampel Filter&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Outlier rejection · σ=3&amp;lt;/small&amp;gt;\&quot;]\n        SUBSEL[\&quot;Subcarrier Selection&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-mincut · sensitive/insensitive split&amp;lt;/small&amp;gt;\&quot;]\n        SPEC[\&quot;Spectrogram&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-attn-mincut · gated STFT&amp;lt;/small&amp;gt;\&quot;]\n        FRESNEL[\&quot;Fresnel Geometry&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-solver · TX-body-RX distance&amp;lt;/small&amp;gt;\&quot;]\n        BVP[\&quot;Body Velocity Profile&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-attention · weighted BVP&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph ML [\&quot;🧠 Neural Pipeline\&quot;]\n        direction TB\n        GRAPH[\&quot;Graph Transformer&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;17 COCO keypoints · 16 edges&amp;lt;/small&amp;gt;\&quot;]\n        CROSS[\&quot;Cross-Attention&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;CSI features → body pose&amp;lt;/small&amp;gt;\&quot;]\n        SONA[\&quot;SONA Adapter&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;LoRA rank-4 · EWC++&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph VITAL [\&quot;💓 Vital Signs\&quot;]\n        direction LR\n        BREATH[\&quot;Breathing&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;0.1–0.5 Hz · FFT peak&amp;lt;/small&amp;gt;\&quot;]\n        HEART[\&quot;Heart Rate&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;0.8–2.0 Hz · FFT peak&amp;lt;/small&amp;gt;\&quot;]\n        MOTION[\&quot;Motion Level&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Variance + band power&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph API [\&quot;🌐 Output Layer\&quot;]\n        direction LR\n        REST[\&quot;REST API&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Axum :3000 · 6 endpoints&amp;lt;/small&amp;gt;\&quot;]\n        WS[\&quot;WebSocket&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;:3001 · real-time stream&amp;lt;/small&amp;gt;\&quot;]\n        ANALYTICS[\&quot;Analytics&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Fall · Activity · START triage&amp;lt;/small&amp;gt;\&quot;]\n        UI[\&quot;Web UI&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Three.js · Gaussian splats&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    R1 &amp;amp; R2 &amp;amp; R3 --&amp;gt; AGG\n    ESP --&amp;gt; AGG\n    WIN --&amp;gt; BRIDGE\n    AGG --&amp;gt; BRIDGE\n    BRIDGE --&amp;gt; PHASE\n    PHASE --&amp;gt; HAMPEL\n    HAMPEL --&amp;gt; SUBSEL\n    SUBSEL --&amp;gt; SPEC\n    SPEC --&amp;gt; FRESNEL\n    FRESNEL --&amp;gt; BVP\n    BVP --&amp;gt; GRAPH\n    GRAPH --&amp;gt; CROSS\n    CROSS --&amp;gt; SONA\n    SONA --&amp;gt; BREATH &amp;amp; HEART &amp;amp; MOTION\n    BREATH &amp;amp; HEART &amp;amp; MOTION --&amp;gt; REST &amp;amp; WS &amp;amp; ANALYTICS\n    WS --&amp;gt; UI\n\n    style HW fill:#1a1a2e,stroke:#e94560,color:#eee\n    style INGEST fill:#16213e,stroke:#0f3460,color:#eee\n    style SIGNAL fill:#0f3460,stroke:#533483,color:#eee\n    style ML fill:#533483,stroke:#e94560,color:#eee\n    style VITAL fill:#2d132c,stroke:#e94560,color:#eee\n    style API fill:#1a1a2e,stroke:#0f3460,color:#eee\n&quot;}" data-plain="graph TB
    subgraph HW [&quot;📡 Hardware Layer&quot;]
        direction LR
        R1[&quot;WiFi Router 1&lt;br/&gt;&lt;small&gt;CSI Source&lt;/small&gt;&quot;]
        R2[&quot;WiFi Router 2&lt;br/&gt;&lt;small&gt;CSI Source&lt;/small&gt;&quot;]
        R3[&quot;WiFi Router 3&lt;br/&gt;&lt;small&gt;CSI Source&lt;/small&gt;&quot;]
        ESP[&quot;ESP32-S3 Mesh&lt;br/&gt;&lt;small&gt;20 Hz · 56 subcarriers&lt;/small&gt;&quot;]
        WIN[&quot;Windows WiFi&lt;br/&gt;&lt;small&gt;RSSI scanning&lt;/small&gt;&quot;]
    end

    subgraph INGEST [&quot;⚡ Ingestion&quot;]
        AGG[&quot;Aggregator&lt;br/&gt;&lt;small&gt;UDP :5005 · ADR-018 frames&lt;/small&gt;&quot;]
        BRIDGE[&quot;Bridge&lt;br/&gt;&lt;small&gt;I/Q → amplitude + phase&lt;/small&gt;&quot;]
    end

    subgraph SIGNAL [&quot;🔬 Signal Processing — RuVector v2.0.4&quot;]
        direction TB
        PHASE[&quot;Phase Sanitization&lt;br/&gt;&lt;small&gt;SpotFi conjugate multiply&lt;/small&gt;&quot;]
        HAMPEL[&quot;Hampel Filter&lt;br/&gt;&lt;small&gt;Outlier rejection · σ=3&lt;/small&gt;&quot;]
        SUBSEL[&quot;Subcarrier Selection&lt;br/&gt;&lt;small&gt;ruvector-mincut · sensitive/insensitive split&lt;/small&gt;&quot;]
        SPEC[&quot;Spectrogram&lt;br/&gt;&lt;small&gt;ruvector-attn-mincut · gated STFT&lt;/small&gt;&quot;]
        FRESNEL[&quot;Fresnel Geometry&lt;br/&gt;&lt;small&gt;ruvector-solver · TX-body-RX distance&lt;/small&gt;&quot;]
        BVP[&quot;Body Velocity Profile&lt;br/&gt;&lt;small&gt;ruvector-attention · weighted BVP&lt;/small&gt;&quot;]
    end

    subgraph ML [&quot;🧠 Neural Pipeline&quot;]
        direction TB
        GRAPH[&quot;Graph Transformer&lt;br/&gt;&lt;small&gt;17 COCO keypoints · 16 edges&lt;/small&gt;&quot;]
        CROSS[&quot;Cross-Attention&lt;br/&gt;&lt;small&gt;CSI features → body pose&lt;/small&gt;&quot;]
        SONA[&quot;SONA Adapter&lt;br/&gt;&lt;small&gt;LoRA rank-4 · EWC++&lt;/small&gt;&quot;]
    end

    subgraph VITAL [&quot;💓 Vital Signs&quot;]
        direction LR
        BREATH[&quot;Breathing&lt;br/&gt;&lt;small&gt;0.1–0.5 Hz · FFT peak&lt;/small&gt;&quot;]
        HEART[&quot;Heart Rate&lt;br/&gt;&lt;small&gt;0.8–2.0 Hz · FFT peak&lt;/small&gt;&quot;]
        MOTION[&quot;Motion Level&lt;br/&gt;&lt;small&gt;Variance + band power&lt;/small&gt;&quot;]
    end

    subgraph API [&quot;🌐 Output Layer&quot;]
        direction LR
        REST[&quot;REST API&lt;br/&gt;&lt;small&gt;Axum :3000 · 6 endpoints&lt;/small&gt;&quot;]
        WS[&quot;WebSocket&lt;br/&gt;&lt;small&gt;:3001 · real-time stream&lt;/small&gt;&quot;]
        ANALYTICS[&quot;Analytics&lt;br/&gt;&lt;small&gt;Fall · Activity · START triage&lt;/small&gt;&quot;]
        UI[&quot;Web UI&lt;br/&gt;&lt;small&gt;Three.js · Gaussian splats&lt;/small&gt;&quot;]
    end

    R1 &amp; R2 &amp; R3 --&gt; AGG
    ESP --&gt; AGG
    WIN --&gt; BRIDGE
    AGG --&gt; BRIDGE
    BRIDGE --&gt; PHASE
    PHASE --&gt; HAMPEL
    HAMPEL --&gt; SUBSEL
    SUBSEL --&gt; SPEC
    SPEC --&gt; FRESNEL
    FRESNEL --&gt; BVP
    BVP --&gt; GRAPH
    GRAPH --&gt; CROSS
    CROSS --&gt; SONA
    SONA --&gt; BREATH &amp; HEART &amp; MOTION
    BREATH &amp; HEART &amp; MOTION --&gt; REST &amp; WS &amp; ANALYTICS
    WS --&gt; UI

    style HW fill:#1a1a2e,stroke:#e94560,color:#eee
    style INGEST fill:#16213e,stroke:#0f3460,color:#eee
    style SIGNAL fill:#0f3460,stroke:#533483,color:#eee
    style ML fill:#533483,stroke:#e94560,color:#eee
    style VITAL fill:#2d132c,stroke:#e94560,color:#eee
    style API fill:#1a1a2e,stroke:#0f3460,color:#eee
" dir="auto">
    <div class="render-plaintext-hidden" dir="auto">
      <pre lang="mermaid" aria-label="Raw mermaid code">graph TB
    subgraph HW ["📡 Hardware Layer"]
        direction LR
        R1["WiFi Router 1&lt;br/&gt;&lt;small&gt;CSI Source&lt;/small&gt;"]
        R2["WiFi Router 2&lt;br/&gt;&lt;small&gt;CSI Source&lt;/small&gt;"]
        R3["WiFi Router 3&lt;br/&gt;&lt;small&gt;CSI Source&lt;/small&gt;"]
        ESP["ESP32-S3 Mesh&lt;br/&gt;&lt;small&gt;20 Hz · 56 subcarriers&lt;/small&gt;"]
        WIN["Windows WiFi&lt;br/&gt;&lt;small&gt;RSSI scanning&lt;/small&gt;"]
    end

    subgraph INGEST ["⚡ Ingestion"]
        AGG["Aggregator&lt;br/&gt;&lt;small&gt;UDP :5005 · ADR-018 frames&lt;/small&gt;"]
        BRIDGE["Bridge&lt;br/&gt;&lt;small&gt;I/Q → amplitude + phase&lt;/small&gt;"]
    end

    subgraph SIGNAL ["🔬 Signal Processing — RuVector v2.0.4"]
        direction TB
        PHASE["Phase Sanitization&lt;br/&gt;&lt;small&gt;SpotFi conjugate multiply&lt;/small&gt;"]
        HAMPEL["Hampel Filter&lt;br/&gt;&lt;small&gt;Outlier rejection · σ=3&lt;/small&gt;"]
        SUBSEL["Subcarrier Selection&lt;br/&gt;&lt;small&gt;ruvector-mincut · sensitive/insensitive split&lt;/small&gt;"]
        SPEC["Spectrogram&lt;br/&gt;&lt;small&gt;ruvector-attn-mincut · gated STFT&lt;/small&gt;"]
        FRESNEL["Fresnel Geometry&lt;br/&gt;&lt;small&gt;ruvector-solver · TX-body-RX distance&lt;/small&gt;"]
        BVP["Body Velocity Profile&lt;br/&gt;&lt;small&gt;ruvector-attention · weighted BVP&lt;/small&gt;"]
    end

    subgraph ML ["🧠 Neural Pipeline"]
        direction TB
        GRAPH["Graph Transformer&lt;br/&gt;&lt;small&gt;17 COCO keypoints · 16 edges&lt;/small&gt;"]
        CROSS["Cross-Attention&lt;br/&gt;&lt;small&gt;CSI features → body pose&lt;/small&gt;"]
        SONA["SONA Adapter&lt;br/&gt;&lt;small&gt;LoRA rank-4 · EWC++&lt;/small&gt;"]
    end

    subgraph VITAL ["💓 Vital Signs"]
        direction LR
        BREATH["Breathing&lt;br/&gt;&lt;small&gt;0.1–0.5 Hz · FFT peak&lt;/small&gt;"]
        HEART["Heart Rate&lt;br/&gt;&lt;small&gt;0.8–2.0 Hz · FFT peak&lt;/small&gt;"]
        MOTION["Motion Level&lt;br/&gt;&lt;small&gt;Variance + band power&lt;/small&gt;"]
    end

    subgraph API ["🌐 Output Layer"]
        direction LR
        REST["REST API&lt;br/&gt;&lt;small&gt;Axum :3000 · 6 endpoints&lt;/small&gt;"]
        WS["WebSocket&lt;br/&gt;&lt;small&gt;:3001 · real-time stream&lt;/small&gt;"]
        ANALYTICS["Analytics&lt;br/&gt;&lt;small&gt;Fall · Activity · START triage&lt;/small&gt;"]
        UI["Web UI&lt;br/&gt;&lt;small&gt;Three.js · Gaussian splats&lt;/small&gt;"]
    end

    R1 &amp; R2 &amp; R3 --&gt; AGG
    ESP --&gt; AGG
    WIN --&gt; BRIDGE
    AGG --&gt; BRIDGE
    BRIDGE --&gt; PHASE
    PHASE --&gt; HAMPEL
    HAMPEL --&gt; SUBSEL
    SUBSEL --&gt; SPEC
    SPEC --&gt; FRESNEL
    FRESNEL --&gt; BVP
    BVP --&gt; GRAPH
    GRAPH --&gt; CROSS
    CROSS --&gt; SONA
    SONA --&gt; BREATH &amp; HEART &amp; MOTION
    BREATH &amp; HEART &amp; MOTION --&gt; REST &amp; WS &amp; ANALYTICS
    WS --&gt; UI

    style HW fill:#1a1a2e,stroke:#e94560,color:#eee
    style INGEST fill:#16213e,stroke:#0f3460,color:#eee
    style SIGNAL fill:#0f3460,stroke:#533483,color:#eee
    style ML fill:#533483,stroke:#e94560,color:#eee
    style VITAL fill:#2d132c,stroke:#e94560,color:#eee
    style API fill:#1a1a2e,stroke:#0f3460,color:#eee
</pre>
    </div>
  </div>
  <span class="js-render-enrichment-loader d-flex flex-justify-center flex-items-center width-full" style="min-height:100px" role="presentation">
    <span data-view-component="true">
  <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" data-view-component="true" class="octospinner mx-auto anim-rotate">
    <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" fill="none"></circle>
    <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"></path>
</svg>    <span class="sr-only">Loading</span>
</span>
  </span>
</section>

<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Signal Processing Detail</h3><a id="user-content-signal-processing-detail" class="anchor" aria-label="Permalink: Signal Processing Detail" href="#signal-processing-detail"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<section class="js-render-needs-enrichment render-needs-enrichment position-relative" data-identity="4db29df7-3c66-47b6-9b6e-254755989a16" data-host="https://viewscreen.githubusercontent.com" data-src="https://viewscreen.githubusercontent.com/markdown/mermaid?docs_host=https%3A%2F%2Fdocs.github.com" data-type="mermaid" aria-label="mermaid rendered output container">
  <div class="js-render-enrichment-target" data-json="{&quot;data&quot;:&quot;graph LR\n    subgraph RAW [\&quot;Raw CSI Frame\&quot;]\n        IQ[\&quot;I/Q Samples&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;56–192 subcarriers × N antennas&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph CLEAN [\&quot;Phase Cleanup\&quot;]\n        CONJ[\&quot;Conjugate Multiply&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Remove carrier freq offset&amp;lt;/small&amp;gt;\&quot;]\n        UNWRAP[\&quot;Phase Unwrap&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Remove 2π discontinuities&amp;lt;/small&amp;gt;\&quot;]\n        HAMPEL2[\&quot;Hampel Filter&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Remove impulse noise&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph SELECT [\&quot;Subcarrier Intelligence\&quot;]\n        MINCUT[\&quot;Min-Cut Partition&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-mincut&amp;lt;/small&amp;gt;\&quot;]\n        GATE[\&quot;Attention Gate&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-attn-mincut&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph EXTRACT [\&quot;Feature Extraction\&quot;]\n        STFT[\&quot;STFT Spectrogram&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Time-frequency decomposition&amp;lt;/small&amp;gt;\&quot;]\n        FRESNELZ[\&quot;Fresnel Zones&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-solver&amp;lt;/small&amp;gt;\&quot;]\n        BVPE[\&quot;BVP Estimation&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;ruvector-attention&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph OUT [\&quot;Output Features\&quot;]\n        AMP[\&quot;Amplitude Matrix\&quot;]\n        PHASE2[\&quot;Phase Matrix\&quot;]\n        DOPPLER[\&quot;Doppler Shifts\&quot;]\n        VITALS[\&quot;Vital Band Power\&quot;]\n    end\n\n    IQ --&amp;gt; CONJ --&amp;gt; UNWRAP --&amp;gt; HAMPEL2\n    HAMPEL2 --&amp;gt; MINCUT --&amp;gt; GATE\n    GATE --&amp;gt; STFT --&amp;gt; FRESNELZ --&amp;gt; BVPE\n    BVPE --&amp;gt; AMP &amp;amp; PHASE2 &amp;amp; DOPPLER &amp;amp; VITALS\n\n    style RAW fill:#0d1117,stroke:#58a6ff,color:#c9d1d9\n    style CLEAN fill:#161b22,stroke:#58a6ff,color:#c9d1d9\n    style SELECT fill:#161b22,stroke:#d29922,color:#c9d1d9\n    style EXTRACT fill:#161b22,stroke:#3fb950,color:#c9d1d9\n    style OUT fill:#0d1117,stroke:#8b949e,color:#c9d1d9\n&quot;}" data-plain="graph LR
    subgraph RAW [&quot;Raw CSI Frame&quot;]
        IQ[&quot;I/Q Samples&lt;br/&gt;&lt;small&gt;56–192 subcarriers × N antennas&lt;/small&gt;&quot;]
    end

    subgraph CLEAN [&quot;Phase Cleanup&quot;]
        CONJ[&quot;Conjugate Multiply&lt;br/&gt;&lt;small&gt;Remove carrier freq offset&lt;/small&gt;&quot;]
        UNWRAP[&quot;Phase Unwrap&lt;br/&gt;&lt;small&gt;Remove 2π discontinuities&lt;/small&gt;&quot;]
        HAMPEL2[&quot;Hampel Filter&lt;br/&gt;&lt;small&gt;Remove impulse noise&lt;/small&gt;&quot;]
    end

    subgraph SELECT [&quot;Subcarrier Intelligence&quot;]
        MINCUT[&quot;Min-Cut Partition&lt;br/&gt;&lt;small&gt;ruvector-mincut&lt;/small&gt;&quot;]
        GATE[&quot;Attention Gate&lt;br/&gt;&lt;small&gt;ruvector-attn-mincut&lt;/small&gt;&quot;]
    end

    subgraph EXTRACT [&quot;Feature Extraction&quot;]
        STFT[&quot;STFT Spectrogram&lt;br/&gt;&lt;small&gt;Time-frequency decomposition&lt;/small&gt;&quot;]
        FRESNELZ[&quot;Fresnel Zones&lt;br/&gt;&lt;small&gt;ruvector-solver&lt;/small&gt;&quot;]
        BVPE[&quot;BVP Estimation&lt;br/&gt;&lt;small&gt;ruvector-attention&lt;/small&gt;&quot;]
    end

    subgraph OUT [&quot;Output Features&quot;]
        AMP[&quot;Amplitude Matrix&quot;]
        PHASE2[&quot;Phase Matrix&quot;]
        DOPPLER[&quot;Doppler Shifts&quot;]
        VITALS[&quot;Vital Band Power&quot;]
    end

    IQ --&gt; CONJ --&gt; UNWRAP --&gt; HAMPEL2
    HAMPEL2 --&gt; MINCUT --&gt; GATE
    GATE --&gt; STFT --&gt; FRESNELZ --&gt; BVPE
    BVPE --&gt; AMP &amp; PHASE2 &amp; DOPPLER &amp; VITALS

    style RAW fill:#0d1117,stroke:#58a6ff,color:#c9d1d9
    style CLEAN fill:#161b22,stroke:#58a6ff,color:#c9d1d9
    style SELECT fill:#161b22,stroke:#d29922,color:#c9d1d9
    style EXTRACT fill:#161b22,stroke:#3fb950,color:#c9d1d9
    style OUT fill:#0d1117,stroke:#8b949e,color:#c9d1d9
" dir="auto">
    <div class="render-plaintext-hidden" dir="auto">
      <pre lang="mermaid" aria-label="Raw mermaid code">graph LR
    subgraph RAW ["Raw CSI Frame"]
        IQ["I/Q Samples&lt;br/&gt;&lt;small&gt;56–192 subcarriers × N antennas&lt;/small&gt;"]
    end

    subgraph CLEAN ["Phase Cleanup"]
        CONJ["Conjugate Multiply&lt;br/&gt;&lt;small&gt;Remove carrier freq offset&lt;/small&gt;"]
        UNWRAP["Phase Unwrap&lt;br/&gt;&lt;small&gt;Remove 2π discontinuities&lt;/small&gt;"]
        HAMPEL2["Hampel Filter&lt;br/&gt;&lt;small&gt;Remove impulse noise&lt;/small&gt;"]
    end

    subgraph SELECT ["Subcarrier Intelligence"]
        MINCUT["Min-Cut Partition&lt;br/&gt;&lt;small&gt;ruvector-mincut&lt;/small&gt;"]
        GATE["Attention Gate&lt;br/&gt;&lt;small&gt;ruvector-attn-mincut&lt;/small&gt;"]
    end

    subgraph EXTRACT ["Feature Extraction"]
        STFT["STFT Spectrogram&lt;br/&gt;&lt;small&gt;Time-frequency decomposition&lt;/small&gt;"]
        FRESNELZ["Fresnel Zones&lt;br/&gt;&lt;small&gt;ruvector-solver&lt;/small&gt;"]
        BVPE["BVP Estimation&lt;br/&gt;&lt;small&gt;ruvector-attention&lt;/small&gt;"]
    end

    subgraph OUT ["Output Features"]
        AMP["Amplitude Matrix"]
        PHASE2["Phase Matrix"]
        DOPPLER["Doppler Shifts"]
        VITALS["Vital Band Power"]
    end

    IQ --&gt; CONJ --&gt; UNWRAP --&gt; HAMPEL2
    HAMPEL2 --&gt; MINCUT --&gt; GATE
    GATE --&gt; STFT --&gt; FRESNELZ --&gt; BVPE
    BVPE --&gt; AMP &amp; PHASE2 &amp; DOPPLER &amp; VITALS

    style RAW fill:#0d1117,stroke:#58a6ff,color:#c9d1d9
    style CLEAN fill:#161b22,stroke:#58a6ff,color:#c9d1d9
    style SELECT fill:#161b22,stroke:#d29922,color:#c9d1d9
    style EXTRACT fill:#161b22,stroke:#3fb950,color:#c9d1d9
    style OUT fill:#0d1117,stroke:#8b949e,color:#c9d1d9
</pre>
    </div>
  </div>
  <span class="js-render-enrichment-loader d-flex flex-justify-center flex-items-center width-full" style="min-height:100px" role="presentation">
    <span data-view-component="true">
  <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" data-view-component="true" class="octospinner mx-auto anim-rotate">
    <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" fill="none"></circle>
    <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"></path>
</svg>    <span class="sr-only">Loading</span>
</span>
  </span>
</section>

<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Deployment Topology</h3><a id="user-content-deployment-topology" class="anchor" aria-label="Permalink: Deployment Topology" href="#deployment-topology"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<section class="js-render-needs-enrichment render-needs-enrichment position-relative" data-identity="bf99a9a7-98e7-407a-a2fe-6733b650dd3c" data-host="https://viewscreen.githubusercontent.com" data-src="https://viewscreen.githubusercontent.com/markdown/mermaid?docs_host=https%3A%2F%2Fdocs.github.com" data-type="mermaid" aria-label="mermaid rendered output container">
  <div class="js-render-enrichment-target" data-json="{&quot;data&quot;:&quot;graph TB\n    subgraph EDGE [\&quot;Edge (ESP32-S3 Mesh)\&quot;]\n        E1[\&quot;Node 1&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Kitchen&amp;lt;/small&amp;gt;\&quot;]\n        E2[\&quot;Node 2&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Living room&amp;lt;/small&amp;gt;\&quot;]\n        E3[\&quot;Node 3&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Bedroom&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph SERVER [\&quot;Server (Rust · 132 MB Docker)\&quot;]\n        SENSE[\&quot;Sensing Server&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;:3000 REST · :3001 WS · :5005 UDP&amp;lt;/small&amp;gt;\&quot;]\n        RVF[\&quot;RVF Model&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Progressive 3-layer load&amp;lt;/small&amp;gt;\&quot;]\n        STORE[\&quot;Time-Series Store&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;In-memory ring buffer&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    subgraph CLIENT [\&quot;Clients\&quot;]\n        BROWSER[\&quot;Browser&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;Three.js UI · Gaussian splats&amp;lt;/small&amp;gt;\&quot;]\n        MOBILE[\&quot;Mobile App&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;WebSocket stream&amp;lt;/small&amp;gt;\&quot;]\n        DASH[\&quot;Dashboard&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;REST polling&amp;lt;/small&amp;gt;\&quot;]\n        IOT[\&quot;Home Automation&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;MQTT bridge&amp;lt;/small&amp;gt;\&quot;]\n    end\n\n    E1 --&amp;gt;|\&quot;UDP :5005&amp;lt;br/&amp;gt;ADR-018 frames\&quot;| SENSE\n    E2 --&amp;gt;|\&quot;UDP :5005\&quot;| SENSE\n    E3 --&amp;gt;|\&quot;UDP :5005\&quot;| SENSE\n    SENSE &amp;lt;--&amp;gt; RVF\n    SENSE &amp;lt;--&amp;gt; STORE\n    SENSE --&amp;gt;|\&quot;WS :3001&amp;lt;br/&amp;gt;real-time JSON\&quot;| BROWSER &amp;amp; MOBILE\n    SENSE --&amp;gt;|\&quot;REST :3000&amp;lt;br/&amp;gt;on-demand\&quot;| DASH &amp;amp; IOT\n\n    style EDGE fill:#1a1a2e,stroke:#e94560,color:#eee\n    style SERVER fill:#16213e,stroke:#533483,color:#eee\n    style CLIENT fill:#0f3460,stroke:#0f3460,color:#eee\n&quot;}" data-plain="graph TB
    subgraph EDGE [&quot;Edge (ESP32-S3 Mesh)&quot;]
        E1[&quot;Node 1&lt;br/&gt;&lt;small&gt;Kitchen&lt;/small&gt;&quot;]
        E2[&quot;Node 2&lt;br/&gt;&lt;small&gt;Living room&lt;/small&gt;&quot;]
        E3[&quot;Node 3&lt;br/&gt;&lt;small&gt;Bedroom&lt;/small&gt;&quot;]
    end

    subgraph SERVER [&quot;Server (Rust · 132 MB Docker)&quot;]
        SENSE[&quot;Sensing Server&lt;br/&gt;&lt;small&gt;:3000 REST · :3001 WS · :5005 UDP&lt;/small&gt;&quot;]
        RVF[&quot;RVF Model&lt;br/&gt;&lt;small&gt;Progressive 3-layer load&lt;/small&gt;&quot;]
        STORE[&quot;Time-Series Store&lt;br/&gt;&lt;small&gt;In-memory ring buffer&lt;/small&gt;&quot;]
    end

    subgraph CLIENT [&quot;Clients&quot;]
        BROWSER[&quot;Browser&lt;br/&gt;&lt;small&gt;Three.js UI · Gaussian splats&lt;/small&gt;&quot;]
        MOBILE[&quot;Mobile App&lt;br/&gt;&lt;small&gt;WebSocket stream&lt;/small&gt;&quot;]
        DASH[&quot;Dashboard&lt;br/&gt;&lt;small&gt;REST polling&lt;/small&gt;&quot;]
        IOT[&quot;Home Automation&lt;br/&gt;&lt;small&gt;MQTT bridge&lt;/small&gt;&quot;]
    end

    E1 --&gt;|&quot;UDP :5005&lt;br/&gt;ADR-018 frames&quot;| SENSE
    E2 --&gt;|&quot;UDP :5005&quot;| SENSE
    E3 --&gt;|&quot;UDP :5005&quot;| SENSE
    SENSE &lt;--&gt; RVF
    SENSE &lt;--&gt; STORE
    SENSE --&gt;|&quot;WS :3001&lt;br/&gt;real-time JSON&quot;| BROWSER &amp; MOBILE
    SENSE --&gt;|&quot;REST :3000&lt;br/&gt;on-demand&quot;| DASH &amp; IOT

    style EDGE fill:#1a1a2e,stroke:#e94560,color:#eee
    style SERVER fill:#16213e,stroke:#533483,color:#eee
    style CLIENT fill:#0f3460,stroke:#0f3460,color:#eee
" dir="auto">
    <div class="render-plaintext-hidden" dir="auto">
      <pre lang="mermaid" aria-label="Raw mermaid code">graph TB
    subgraph EDGE ["Edge (ESP32-S3 Mesh)"]
        E1["Node 1&lt;br/&gt;&lt;small&gt;Kitchen&lt;/small&gt;"]
        E2["Node 2&lt;br/&gt;&lt;small&gt;Living room&lt;/small&gt;"]
        E3["Node 3&lt;br/&gt;&lt;small&gt;Bedroom&lt;/small&gt;"]
    end

    subgraph SERVER ["Server (Rust · 132 MB Docker)"]
        SENSE["Sensing Server&lt;br/&gt;&lt;small&gt;:3000 REST · :3001 WS · :5005 UDP&lt;/small&gt;"]
        RVF["RVF Model&lt;br/&gt;&lt;small&gt;Progressive 3-layer load&lt;/small&gt;"]
        STORE["Time-Series Store&lt;br/&gt;&lt;small&gt;In-memory ring buffer&lt;/small&gt;"]
    end

    subgraph CLIENT ["Clients"]
        BROWSER["Browser&lt;br/&gt;&lt;small&gt;Three.js UI · Gaussian splats&lt;/small&gt;"]
        MOBILE["Mobile App&lt;br/&gt;&lt;small&gt;WebSocket stream&lt;/small&gt;"]
        DASH["Dashboard&lt;br/&gt;&lt;small&gt;REST polling&lt;/small&gt;"]
        IOT["Home Automation&lt;br/&gt;&lt;small&gt;MQTT bridge&lt;/small&gt;"]
    end

    E1 --&gt;|"UDP :5005&lt;br/&gt;ADR-018 frames"| SENSE
    E2 --&gt;|"UDP :5005"| SENSE
    E3 --&gt;|"UDP :5005"| SENSE
    SENSE &lt;--&gt; RVF
    SENSE &lt;--&gt; STORE
    SENSE --&gt;|"WS :3001&lt;br/&gt;real-time JSON"| BROWSER &amp; MOBILE
    SENSE --&gt;|"REST :3000&lt;br/&gt;on-demand"| DASH &amp; IOT

    style EDGE fill:#1a1a2e,stroke:#e94560,color:#eee
    style SERVER fill:#16213e,stroke:#533483,color:#eee
    style CLIENT fill:#0f3460,stroke:#0f3460,color:#eee
</pre>
    </div>
  </div>
  <span class="js-render-enrichment-loader d-flex flex-justify-center flex-items-center width-full" style="min-height:100px" role="presentation">
    <span data-view-component="true">
  <svg style="box-sizing: content-box; color: var(--color-icon-primary);" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" data-view-component="true" class="octospinner mx-auto anim-rotate">
    <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" fill="none"></circle>
    <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke"></path>
</svg>    <span class="sr-only">Loading</span>
</span>
  </span>
</section>

<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Component</th>
<th>Crate / Module</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Aggregator</strong></td>
<td><code>wifi-densepose-hardware</code></td>
<td>ESP32 UDP listener, ADR-018 frame parser, I/Q → amplitude/phase bridge</td>
</tr>
<tr>
<td><strong>Signal Processor</strong></td>
<td><code>wifi-densepose-signal</code></td>
<td>SpotFi phase sanitization, Hampel filter, STFT spectrogram, Fresnel geometry, BVP</td>
</tr>
<tr>
<td><strong>Subcarrier Selection</strong></td>
<td><code>ruvector-mincut</code> + <code>ruvector-attn-mincut</code></td>
<td>Dynamic sensitive/insensitive partitioning, attention-gated noise suppression</td>
</tr>
<tr>
<td><strong>Fresnel Solver</strong></td>
<td><code>ruvector-solver</code></td>
<td>Sparse Neumann series O(sqrt(n)) for TX-body-RX distance estimation</td>
</tr>
<tr>
<td><strong>Graph Transformer</strong></td>
<td><code>wifi-densepose-train</code></td>
<td>COCO BodyGraph (17 kp, 16 edges), cross-attention CSI→pose, GCN message passing</td>
</tr>
<tr>
<td><strong>SONA</strong></td>
<td><code>sona</code> crate</td>
<td>Micro-LoRA (rank-4) adaptation, EWC++ catastrophic forgetting prevention</td>
</tr>
<tr>
<td><strong>Vital Signs</strong></td>
<td><code>wifi-densepose-signal</code></td>
<td>FFT-based breathing (0.1-0.5 Hz) and heartbeat (0.8-2.0 Hz) extraction</td>
</tr>
<tr>
<td><strong>REST API</strong></td>
<td><code>wifi-densepose-sensing-server</code></td>
<td>Axum server: <code>/api/v1/sensing</code>, <code>/health</code>, <code>/vital-signs</code>, <code>/bssid</code>, <code>/sona</code></td>
</tr>
<tr>
<td><strong>WebSocket</strong></td>
<td><code>wifi-densepose-sensing-server</code></td>
<td>Real-time pose, sensing, and vital sign streaming on <code>:3001</code></td>
</tr>
<tr>
<td><strong>Analytics</strong></td>
<td><code>wifi-densepose-mat</code></td>
<td>Fall detection, activity recognition, START triage (WiFi-Mat disaster module)</td>
</tr>
<tr>
<td><strong>Web UI</strong></td>
<td><code>ui/</code></td>
<td>Three.js scene, Gaussian splat visualization, signal dashboard</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🖥️ CLI Usage</h2><a id="user-content-️-cli-usage" class="anchor" aria-label="Permalink: 🖥️ CLI Usage" href="#️-cli-usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Rust Sensing Server</strong> — Primary CLI interface</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Start with simulated data (no hardware)
./target/release/sensing-server --source simulate --ui-path ../../ui

# Start with ESP32 CSI hardware
./target/release/sensing-server --source esp32 --udp-port 5005

# Start with Windows WiFi RSSI
./target/release/sensing-server --source wifi

# Run vital sign benchmark
./target/release/sensing-server --benchmark

# Export RVF model package
./target/release/sensing-server --export-rvf model.rvf

# Train a model
./target/release/sensing-server --train --dataset data/ --epochs 100

# Load trained model with progressive loading
./target/release/sensing-server --model wifi-densepose-v1.rvf --progressive"><pre><span class="pl-c"><span class="pl-c">#</span> Start with simulated data (no hardware)</span>
./target/release/sensing-server --source simulate --ui-path ../../ui

<span class="pl-c"><span class="pl-c">#</span> Start with ESP32 CSI hardware</span>
./target/release/sensing-server --source esp32 --udp-port 5005

<span class="pl-c"><span class="pl-c">#</span> Start with Windows WiFi RSSI</span>
./target/release/sensing-server --source wifi

<span class="pl-c"><span class="pl-c">#</span> Run vital sign benchmark</span>
./target/release/sensing-server --benchmark

<span class="pl-c"><span class="pl-c">#</span> Export RVF model package</span>
./target/release/sensing-server --export-rvf model.rvf

<span class="pl-c"><span class="pl-c">#</span> Train a model</span>
./target/release/sensing-server --train --dataset data/ --epochs 100

<span class="pl-c"><span class="pl-c">#</span> Load trained model with progressive loading</span>
./target/release/sensing-server --model wifi-densepose-v1.rvf --progressive</pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Flag</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--source</code></td>
<td>Data source: <code>auto</code>, <code>wifi</code>, <code>esp32</code>, <code>simulate</code></td>
</tr>
<tr>
<td><code>--http-port</code></td>
<td>HTTP port for UI and REST API (default: 8080)</td>
</tr>
<tr>
<td><code>--ws-port</code></td>
<td>WebSocket port (default: 8765)</td>
</tr>
<tr>
<td><code>--udp-port</code></td>
<td>UDP port for ESP32 CSI frames (default: 5005)</td>
</tr>
<tr>
<td><code>--benchmark</code></td>
<td>Run vital sign benchmark (1000 frames) and exit</td>
</tr>
<tr>
<td><code>--export-rvf</code></td>
<td>Export RVF container package and exit</td>
</tr>
<tr>
<td><code>--load-rvf</code></td>
<td>Load model config from RVF container</td>
</tr>
<tr>
<td><code>--save-rvf</code></td>
<td>Save model state on shutdown</td>
</tr>
<tr>
<td><code>--model</code></td>
<td>Load trained <code>.rvf</code> model for inference</td>
</tr>
<tr>
<td><code>--progressive</code></td>
<td>Enable progressive loading (Layer A instant start)</td>
</tr>
<tr>
<td><code>--train</code></td>
<td>Train a model and exit</td>
</tr>
<tr>
<td><code>--dataset</code></td>
<td>Path to dataset directory (MM-Fi or Wi-Pose)</td>
</tr>
<tr>
<td><code>--epochs</code></td>
<td>Training epochs (default: 100)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><a id="user-content-rest-api--websocket"></a><strong>REST API &amp; WebSocket</strong> — Endpoints reference</summary>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">REST API (Rust Sensing Server)</h4><a id="user-content-rest-api-rust-sensing-server" class="anchor" aria-label="Permalink: REST API (Rust Sensing Server)" href="#rest-api-rust-sensing-server"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="GET  /api/v1/sensing              # Latest sensing frame
GET  /api/v1/vital-signs          # Breathing, heart rate, confidence
GET  /api/v1/bssid                # Multi-BSSID registry
GET  /api/v1/model/layers         # Progressive loading status
GET  /api/v1/model/sona/profiles  # SONA profiles
POST /api/v1/model/sona/activate  # Activate SONA profile"><pre>GET  /api/v1/sensing              <span class="pl-c"><span class="pl-c">#</span> Latest sensing frame</span>
GET  /api/v1/vital-signs          <span class="pl-c"><span class="pl-c">#</span> Breathing, heart rate, confidence</span>
GET  /api/v1/bssid                <span class="pl-c"><span class="pl-c">#</span> Multi-BSSID registry</span>
GET  /api/v1/model/layers         <span class="pl-c"><span class="pl-c">#</span> Progressive loading status</span>
GET  /api/v1/model/sona/profiles  <span class="pl-c"><span class="pl-c">#</span> SONA profiles</span>
POST /api/v1/model/sona/activate  <span class="pl-c"><span class="pl-c">#</span> Activate SONA profile</span></pre></div>
<p dir="auto">WebSocket: <code>ws://localhost:3001/ws/sensing</code> (real-time sensing + vital signs)</p>
<blockquote>
<p dir="auto">Default ports (Docker): HTTP 3000, WS 3001. Binary defaults: HTTP 8080, WS 8765. Override with <code>--http-port</code> / <code>--ws-port</code>.</p>
</blockquote>
</details>
<details>
<summary><a id="user-content-hardware-support-1"></a><strong>Hardware Support</strong> — Devices, cost, and guides</summary>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Hardware</th>
<th>CSI</th>
<th>Cost</th>
<th>Guide</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ESP32-S3</strong></td>
<td>Native</td>
<td>~$8</td>
<td><a href="https://github.com/ruvnet/RuView/issues/34" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/34/hovercard">Tutorial #34</a></td>
</tr>
<tr>
<td>Intel 5300</td>
<td>Firmware mod</td>
<td>~$15</td>
<td>Linux <code>iwl-csi</code></td>
</tr>
<tr>
<td>Atheros AR9580</td>
<td>ath9k patch</td>
<td>~$20</td>
<td>Linux only</td>
</tr>
<tr>
<td>Any Windows WiFi</td>
<td>RSSI only</td>
<td>$0</td>
<td><a href="https://github.com/ruvnet/RuView/issues/36" data-hovercard-type="issue" data-hovercard-url="/ruvnet/RuView/issues/36/hovercard">Tutorial #36</a></td>
</tr>
<tr>
<td>Any macOS WiFi</td>
<td>RSSI only (CoreWLAN)</td>
<td>$0</td>
<td><a href="docs/adr/ADR-025-macos-corewlan-wifi-sensing.md">ADR-025</a></td>
</tr>
<tr>
<td>Any Linux WiFi</td>
<td>RSSI only (<code>iw</code>)</td>
<td>$0</td>
<td>Requires <code>iw</code> + <code>CAP_NET_ADMIN</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<details>
<summary><strong>Python Legacy CLI</strong> — v1 API server commands</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="wifi-densepose start                    # Start API server
wifi-densepose -c config.yaml start     # Custom config
wifi-densepose -v start                 # Verbose logging
wifi-densepose status                   # Check status
wifi-densepose stop                     # Stop server
wifi-densepose config show              # Show configuration
wifi-densepose db init                  # Initialize database
wifi-densepose tasks list               # List background tasks"><pre>wifi-densepose start                    <span class="pl-c"><span class="pl-c">#</span> Start API server</span>
wifi-densepose -c config.yaml start     <span class="pl-c"><span class="pl-c">#</span> Custom config</span>
wifi-densepose -v start                 <span class="pl-c"><span class="pl-c">#</span> Verbose logging</span>
wifi-densepose status                   <span class="pl-c"><span class="pl-c">#</span> Check status</span>
wifi-densepose stop                     <span class="pl-c"><span class="pl-c">#</span> Stop server</span>
wifi-densepose config show              <span class="pl-c"><span class="pl-c">#</span> Show configuration</span>
wifi-densepose db init                  <span class="pl-c"><span class="pl-c">#</span> Initialize database</span>
wifi-densepose tasks list               <span class="pl-c"><span class="pl-c">#</span> List background tasks</span></pre></div>
</details>
<details>
<summary><strong>Documentation Links</strong></summary>
<ul dir="auto">
<li><a href="docs/wifi-mat-user-guide.md">WiFi-Mat User Guide</a> | <a href="docs/ddd/wifi-mat-domain-model.md">Domain Model</a></li>
<li><a href="docs/adr/ADR-021-vital-sign-detection-rvdna-pipeline.md">ADR-021</a> | <a href="docs/adr/ADR-022-windows-wifi-enhanced-fidelity-ruvector.md">ADR-022</a> | <a href="docs/adr/ADR-023-trained-densepose-model-ruvector-pipeline.md">ADR-023</a></li>
</ul>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🧪 Testing</h2><a id="user-content--testing" class="anchor" aria-label="Permalink: 🧪 Testing" href="#-testing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>542+ tests across 7 suites</strong> — zero mocks, hardware-free simulation</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Rust tests (primary — 542+ tests)
cd rust-port/wifi-densepose-rs
cargo test --workspace

# Sensing server tests (229 tests)
cargo test -p wifi-densepose-sensing-server

# Vital sign benchmark
./target/release/sensing-server --benchmark

# Python tests
python -m pytest v1/tests/ -v

# Pipeline verification (no hardware needed)
./verify"><pre><span class="pl-c"><span class="pl-c">#</span> Rust tests (primary — 542+ tests)</span>
<span class="pl-c1">cd</span> rust-port/wifi-densepose-rs
cargo <span class="pl-c1">test</span> --workspace

<span class="pl-c"><span class="pl-c">#</span> Sensing server tests (229 tests)</span>
cargo <span class="pl-c1">test</span> -p wifi-densepose-sensing-server

<span class="pl-c"><span class="pl-c">#</span> Vital sign benchmark</span>
./target/release/sensing-server --benchmark

<span class="pl-c"><span class="pl-c">#</span> Python tests</span>
python -m pytest v1/tests/ -v

<span class="pl-c"><span class="pl-c">#</span> Pipeline verification (no hardware needed)</span>
./verify</pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Suite</th>
<th>Tests</th>
<th>What It Covers</th>
</tr>
</thead>
<tbody>
<tr>
<td>sensing-server lib</td>
<td>147</td>
<td>Graph transformer, trainer, SONA, sparse inference, RVF</td>
</tr>
<tr>
<td>sensing-server bin</td>
<td>48</td>
<td>CLI integration, WebSocket, REST API</td>
</tr>
<tr>
<td>RVF integration</td>
<td>16</td>
<td>Container build, read, progressive load</td>
</tr>
<tr>
<td>Vital signs integration</td>
<td>18</td>
<td>FFT detection, breathing, heartbeat</td>
</tr>
<tr>
<td>wifi-densepose-signal</td>
<td>83</td>
<td>SOTA algorithms, Doppler, Fresnel</td>
</tr>
<tr>
<td>wifi-densepose-mat</td>
<td>139</td>
<td>Disaster response, triage, localization</td>
</tr>
<tr>
<td>wifi-densepose-wifiscan</td>
<td>91</td>
<td>8-stage RSSI pipeline</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🚀 Deployment</h2><a id="user-content--deployment" class="anchor" aria-label="Permalink: 🚀 Deployment" href="#-deployment"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Docker deployment</strong> — Production setup with docker-compose</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Rust sensing server (132 MB)
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 -p 3001:3001 -p 5005:5005/udp ruvnet/wifi-densepose:latest

# Python pipeline (569 MB)
docker pull ruvnet/wifi-densepose:python
docker run -p 8765:8765 -p 8080:8080 ruvnet/wifi-densepose:python

# Both via docker-compose
cd docker &amp;&amp; docker compose up

# Export RVF model
docker run --rm -v $(pwd):/out ruvnet/wifi-densepose:latest --export-rvf /out/model.rvf"><pre><span class="pl-c"><span class="pl-c">#</span> Rust sensing server (132 MB)</span>
docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 -p 3001:3001 -p 5005:5005/udp ruvnet/wifi-densepose:latest

<span class="pl-c"><span class="pl-c">#</span> Python pipeline (569 MB)</span>
docker pull ruvnet/wifi-densepose:python
docker run -p 8765:8765 -p 8080:8080 ruvnet/wifi-densepose:python

<span class="pl-c"><span class="pl-c">#</span> Both via docker-compose</span>
<span class="pl-c1">cd</span> docker <span class="pl-k">&amp;&amp;</span> docker compose up

<span class="pl-c"><span class="pl-c">#</span> Export RVF model</span>
docker run --rm -v <span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>:/out ruvnet/wifi-densepose:latest --export-rvf /out/model.rvf</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Environment Variables</h3><a id="user-content-environment-variables" class="anchor" aria-label="Permalink: Environment Variables" href="#environment-variables"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="RUST_LOG=info                    # Logging level
WIFI_INTERFACE=wlan0             # WiFi interface for RSSI
POSE_CONFIDENCE_THRESHOLD=0.7    # Minimum confidence
POSE_MAX_PERSONS=10              # Max tracked individuals"><pre>RUST_LOG=info                    <span class="pl-c"><span class="pl-c">#</span> Logging level</span>
WIFI_INTERFACE=wlan0             <span class="pl-c"><span class="pl-c">#</span> WiFi interface for RSSI</span>
POSE_CONFIDENCE_THRESHOLD=0.7    <span class="pl-c"><span class="pl-c">#</span> Minimum confidence</span>
POSE_MAX_PERSONS=10              <span class="pl-c"><span class="pl-c">#</span> Max tracked individuals</span></pre></div>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📊 Performance Metrics</h2><a id="user-content--performance-metrics" class="anchor" aria-label="Permalink: 📊 Performance Metrics" href="#-performance-metrics"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Measured benchmarks</strong> — Rust sensing server, validated via cargo bench</summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Rust Sensing Server</h3><a id="user-content-rust-sensing-server" class="anchor" aria-label="Permalink: Rust Sensing Server" href="#rust-sensing-server"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Metric</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Vital sign detection</td>
<td><strong>11,665 fps</strong> (86 µs/frame)</td>
</tr>
<tr>
<td>Full CSI pipeline</td>
<td><strong>54,000 fps</strong> (18.47 µs/frame)</td>
</tr>
<tr>
<td>Motion detection</td>
<td><strong>186 ns</strong> (~5,400x vs Python)</td>
</tr>
<tr>
<td>Docker image</td>
<td>132 MB</td>
</tr>
<tr>
<td>Memory usage</td>
<td>~100 MB</td>
</tr>
<tr>
<td>Test count</td>
<td>542+</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Python vs Rust</h3><a id="user-content-python-vs-rust" class="anchor" aria-label="Permalink: Python vs Rust" href="#python-vs-rust"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Operation</th>
<th>Python</th>
<th>Rust</th>
<th>Speedup</th>
</tr>
</thead>
<tbody>
<tr>
<td>CSI Preprocessing</td>
<td>~5 ms</td>
<td>5.19 µs</td>
<td>1000x</td>
</tr>
<tr>
<td>Phase Sanitization</td>
<td>~3 ms</td>
<td>3.84 µs</td>
<td>780x</td>
</tr>
<tr>
<td>Feature Extraction</td>
<td>~8 ms</td>
<td>9.03 µs</td>
<td>890x</td>
</tr>
<tr>
<td>Motion Detection</td>
<td>~1 ms</td>
<td>186 ns</td>
<td>5400x</td>
</tr>
<tr>
<td><strong>Full Pipeline</strong></td>
<td>~15 ms</td>
<td>18.47 µs</td>
<td><strong>810x</strong></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🤝 Contributing</h2><a id="user-content--contributing" class="anchor" aria-label="Permalink: 🤝 Contributing" href="#-contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Dev setup, code standards, PR process</strong></summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/ruvnet/RuView.git
cd RuView

# Rust development
cd rust-port/wifi-densepose-rs
cargo build --release
cargo test --workspace

# Python development
python -m venv venv &amp;&amp; source venv/bin/activate
pip install -r requirements-dev.txt &amp;&amp; pip install -e .
pre-commit install"><pre>git clone https://github.com/ruvnet/RuView.git
<span class="pl-c1">cd</span> RuView

<span class="pl-c"><span class="pl-c">#</span> Rust development</span>
<span class="pl-c1">cd</span> rust-port/wifi-densepose-rs
cargo build --release
cargo <span class="pl-c1">test</span> --workspace

<span class="pl-c"><span class="pl-c">#</span> Python development</span>
python -m venv venv <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">source</span> venv/bin/activate
pip install -r requirements-dev.txt <span class="pl-k">&amp;&amp;</span> pip install -e <span class="pl-c1">.</span>
pre-commit install</pre></div>
<ol dir="auto">
<li><strong>Fork</strong> the repository</li>
<li><strong>Create</strong> a feature branch (<code>git checkout -b feature/amazing-feature</code>)</li>
<li><strong>Commit</strong> your changes</li>
<li><strong>Push</strong> and open a Pull Request</li>
</ol>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📄 Changelog</h2><a id="user-content--changelog" class="anchor" aria-label="Permalink: 📄 Changelog" href="#-changelog"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details>
<summary><strong>Release history</strong></summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">v3.2.0 — 2026-03-03</h3><a id="user-content-v320--2026-03-03" class="anchor" aria-label="Permalink: v3.2.0 — 2026-03-03" href="#v320--2026-03-03"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Edge intelligence: 24 hot-loadable WASM modules for on-device CSI processing on ESP32-S3.</p>
<ul dir="auto">
<li><strong>ADR-041 Edge Intelligence Modules</strong> — 24 <code>no_std</code> Rust modules compiled to <code>wasm32-unknown-unknown</code>, loaded via WASM3 on ESP32; 8 categories covering signal intelligence, adaptive learning, spatial reasoning, temporal analysis, AI security, quantum-inspired, autonomous systems, and exotic algorithms</li>
<li><strong>Vendor Integration</strong> — Algorithms ported from <code>midstream</code> (DTW, attractors, Flash Attention, min-cut, optimal transport) and <code>sublinear-time-solver</code> (PageRank, HNSW, sparse recovery, spiking NN)</li>
<li><strong>On-device gesture learning</strong> — User-teachable DTW gesture recognition with 3-rehearsal protocol and 16 template slots</li>
<li><strong>Lifelong learning (EWC++)</strong> — Elastic Weight Consolidation prevents catastrophic forgetting when learning new tasks</li>
<li><strong>AI security modules</strong> — FNV-1a replay detection, injection/jamming detection, 6D behavioral anomaly profiling with Mahalanobis scoring</li>
<li><strong>Self-healing mesh</strong> — 8-node mesh with health tracking, degradation/recovery hysteresis, and coverage redistribution</li>
<li><strong>Common utility library</strong> — <code>vendor_common.rs</code> shared across all 24 modules: CircularBuffer, EMA, WelfordStats, DTW, FixedPriorityQueue, vector math</li>
<li><strong>243 tests passing</strong> — All modules include comprehensive inline tests; 0 failures</li>
<li><strong>Security audit</strong> — 15 findings addressed (1 critical, 3 high, 6 medium, 5 low)</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">v3.1.0 — 2026-03-02</h3><a id="user-content-v310--2026-03-02" class="anchor" aria-label="Permalink: v3.1.0 — 2026-03-02" href="#v310--2026-03-02"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Multistatic sensing, persistent field model, and cross-viewpoint fusion — the biggest capability jump since v2.0.</p>
<ul dir="auto">
<li><strong>Project RuvSense (ADR-029)</strong> — Multistatic mesh: TDM protocol, channel hopping (ch1/6/11), multi-band frame fusion, coherence gating, 17-keypoint Kalman tracker with re-ID; 10 new signal modules (5,300+ lines)</li>
<li><strong>RuvSense Persistent Field Model (ADR-030)</strong> — 7 exotic sensing tiers: field normal modes (SVD), RF tomography, longitudinal drift detection, intention prediction, cross-room identity, gesture classification, adversarial detection</li>
<li><strong>Project RuView (ADR-031)</strong> — Cross-viewpoint attention with geometric bias, Geometric Diversity Index, viewpoint fusion orchestrator; 5 new ruvector modules (2,200+ lines)</li>
<li><strong>TDM Hardware Protocol</strong> — ESP32 sensing coordinator: sync beacons, slot scheduling, clock drift compensation (±10ppm), 20 Hz aggregate rate</li>
<li><strong>Channel-Hopping Firmware</strong> — ESP32 firmware extended with hop table, timer-driven channel switching, NDP injection stub; NVS config for all TDM parameters; fully backward-compatible</li>
<li><strong>DDD Domain Model</strong> — 6 bounded contexts, ubiquitous language, aggregate roots, domain events, full event bus specification</li>
<li><strong><code>ruvector-crv</code> 6-stage CRV signal-line integration (ADR-033)</strong> — Maps Coordinate Remote Viewing methodology to WiFi CSI: gestalt classification, sensory encoding, GNN topology, SNN coherence gating, differentiable search, MinCut partitioning; cross-session convergence for multi-room identity continuity</li>
<li><strong>ADR-032 multistatic mesh security hardening</strong> — HMAC-SHA256 beacon auth, SipHash-2-4 frame integrity, NDP rate limiter, coherence gate timeout, bounded buffers, NVS credential zeroing, atomic firmware state</li>
<li><strong>ADR-032a QUIC transport layer</strong> — <code>midstreamer-quic</code> TLS 1.3 AEAD for aggregator nodes, dual-mode security (ManualCrypto/QuicTransport), QUIC stream mapping, connection migration, congestion control</li>
<li><strong>ADR-033 CRV signal-line sensing integration</strong> — Architecture decision record for the 6-stage CRV pipeline mapping to ruvector components</li>
<li><strong>Temporal gesture matching</strong> — <code>midstreamer-temporal-compare</code> DTW/LCS/edit-distance gesture classification with quantized feature comparison</li>
<li><strong>Attractor drift analysis</strong> — <code>midstreamer-attractor</code> Takens' theorem phase-space embedding with Lyapunov exponent regime detection (Stable/Periodic/Chaotic)</li>
<li><strong>v0.3.0 published</strong> — All 15 workspace crates published to <a href="https://crates.io/crates/wifi-densepose-core" rel="nofollow">crates.io</a> with updated dependencies</li>
<li><strong>28,000+ lines of new Rust code</strong> across 26 modules with 400+ tests</li>
<li><strong>Security hardened</strong> — Bounded buffers, NaN guards, no panics in public APIs, input validation at all boundaries</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">v3.0.0 — 2026-03-01</h3><a id="user-content-v300--2026-03-01" class="anchor" aria-label="Permalink: v3.0.0 — 2026-03-01" href="#v300--2026-03-01"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Major release: AETHER contrastive embedding model, AI signal processing backbone, cross-platform adapters, Docker Hub images, and comprehensive README overhaul.</p>
<ul dir="auto">
<li><strong>Project AETHER (ADR-024)</strong> — Self-supervised contrastive learning for WiFi CSI fingerprinting, similarity search, and anomaly detection; 55 KB model fits on ESP32</li>
<li><strong>AI Backbone (<code>wifi-densepose-ruvector</code>)</strong> — 7 RuVector integration points replacing hand-tuned thresholds with attention, graph algorithms, and smart compression; <a href="https://crates.io/crates/wifi-densepose-ruvector" rel="nofollow">published to crates.io</a></li>
<li><strong>Cross-platform RSSI adapters</strong> — macOS CoreWLAN and Linux <code>iw</code> Rust adapters with <code>#[cfg(target_os)]</code> gating (ADR-025)</li>
<li><strong>Docker images published</strong> — <code>ruvnet/wifi-densepose:latest</code> (132 MB Rust) and <code>:python</code> (569 MB)</li>
<li><strong>Project MERIDIAN (ADR-027)</strong> — Cross-environment domain generalization: gradient reversal, geometry-conditioned FiLM, virtual domain augmentation, contrastive test-time training; zero-shot room transfer</li>
<li><strong>10-phase DensePose training pipeline (ADR-023/027)</strong> — Graph transformer, 6-term composite loss, SONA adaptation, RVF packaging, hardware normalization, domain-adversarial training</li>
<li><strong>Vital sign detection (ADR-021)</strong> — FFT-based breathing (6-30 BPM) and heartbeat (40-120 BPM), 11,665 fps</li>
<li><strong>WiFi scan domain layer (ADR-022/025)</strong> — 8-stage signal intelligence pipeline for Windows, macOS, and Linux</li>
<li><strong>700+ Rust tests</strong> — All passing, zero mocks</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">v2.0.0 — 2026-02-28</h3><a id="user-content-v200--2026-02-28" class="anchor" aria-label="Permalink: v2.0.0 — 2026-02-28" href="#v200--2026-02-28"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Complete Rust sensing server, SOTA signal processing, WiFi-Mat disaster response, ESP32 hardware, RuVector integration, guided installer, and security hardening.</p>
<ul dir="auto">
<li><strong>Rust sensing server</strong> — Axum REST API + WebSocket, 810x speedup over Python, 54K fps pipeline</li>
<li><strong>RuVector integration</strong> — 11 vendored crates for HNSW, attention, GNN, temporal compression, min-cut, solver</li>
<li><strong>6 SOTA signal algorithms (ADR-014)</strong> — SpotFi, Hampel, Fresnel, spectrogram, subcarrier selection, BVP</li>
<li><strong>WiFi-Mat disaster response</strong> — START triage, 3D localization, priority alerts — 139 tests</li>
<li><strong>ESP32 CSI hardware</strong> — Binary frame parsing, $54 starter kit, 20 Hz streaming</li>
<li><strong>Guided installer</strong> — 7-step hardware detection, 8 install profiles</li>
<li><strong>Three.js visualization</strong> — 3D body model, 17 joints, real-time WebSocket</li>
<li><strong>Security hardening</strong> — 10 vulnerabilities fixed</li>
</ul>
</details>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📄 License</h2><a id="user-content--license" class="anchor" aria-label="Permalink: 📄 License" href="#-license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT License — see <a href="LICENSE">LICENSE</a> for details.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📞 Support</h2><a id="user-content--support" class="anchor" aria-label="Permalink: 📞 Support" href="#-support"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a href="https://github.com/ruvnet/RuView/issues">GitHub Issues</a> | <a href="https://github.com/ruvnet/RuView/discussions">Discussions</a> | <a href="https://pypi.org/project/wifi-densepose/" rel="nofollow">PyPI</a></p>
<hr>
<p dir="auto"><strong>WiFi DensePose</strong> — Privacy-preserving human pose estimation through WiFi signals.</p>
</article></div>]]></description>
      <link>https://github.com/ruvnet/RuView</link>
      <guid>https://github.com/ruvnet/RuView</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Agentic Engineering Patterns - Simon Willison's Weblog]]></title>
      <description><![CDATA[Agentic Engineering Patterns - Simon Willison's Weblog
<p> Postman — Every API your agents depend on, mapped and monitored. <a href="https://fandf.co/40IFB7j" rel="sponsored noopener" target="_blank">See what's new</a></p>
<div id="wrapper"><div id="primary"><p>Patterns for getting the best results out of coding agents like Claude Code and OpenAI Codex. See <a href="https://simonwillison.net/2026/Feb/23/agentic-engineering-patterns/">my introduction</a> for more on this project.</p><ol class="c2"><li class="c1"><strong>Principles</strong>
<ol><li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/code-is-cheap/">Writing code is cheap now</a></li>
<li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/hoard-things-you-know-how-to-do/">Hoard things you know how to do</a></li>
<li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/anti-patterns/">Anti-patterns: things to avoid</a></li>
<li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/better-code/">AI should help us produce better code</a></li>
</ol></li>
<li class="c1"><strong>Testing and QA</strong>
<ol><li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/red-green-tdd/">Red/green TDD</a></li>
<li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/first-run-the-tests/">First run the tests</a></li>
<li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/agentic-manual-testing/">Agentic manual testing</a></li>
</ol></li>
<li class="c1"><strong>Understanding code</strong>
<ol><li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/linear-walkthroughs/">Linear walkthroughs</a></li>
<li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/interactive-explanations/">Interactive explanations</a></li>
</ol></li>
<li class="c1"><strong>Annotated prompts</strong>
<ol><li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/gif-optimization/">GIF optimization tool using WebAssembly and Gifsicle</a></li>
</ol></li>
<li class="c1"><strong>Appendix</strong>
<ol><li class="c1"><a href="https://simonwillison.net/guides/agentic-engineering-patterns/prompts/">Prompts I use</a></li>
</ol></li>
</ol></div></div>
<div id="ft"><ul><li><a href="https://simonwillison.net/about/#disclosures">Disclosures</a></li>
<li><a href="https://simonwillison.net/about/#about-site">Colophon</a></li>
<li>©</li>
<li><a href="https://simonwillison.net/2002/">2002</a></li>
<li><a href="https://simonwillison.net/2003/">2003</a></li>
<li><a href="https://simonwillison.net/2004/">2004</a></li>
<li><a href="https://simonwillison.net/2005/">2005</a></li>
<li><a href="https://simonwillison.net/2006/">2006</a></li>
<li><a href="https://simonwillison.net/2007/">2007</a></li>
<li><a href="https://simonwillison.net/2008/">2008</a></li>
<li><a href="https://simonwillison.net/2009/">2009</a></li>
<li><a href="https://simonwillison.net/2010/">2010</a></li>
<li><a href="https://simonwillison.net/2011/">2011</a></li>
<li><a href="https://simonwillison.net/2012/">2012</a></li>
<li><a href="https://simonwillison.net/2013/">2013</a></li>
<li><a href="https://simonwillison.net/2014/">2014</a></li>
<li><a href="https://simonwillison.net/2015/">2015</a></li>
<li><a href="https://simonwillison.net/2016/">2016</a></li>
<li><a href="https://simonwillison.net/2017/">2017</a></li>
<li><a href="https://simonwillison.net/2018/">2018</a></li>
<li><a href="https://simonwillison.net/2019/">2019</a></li>
<li><a href="https://simonwillison.net/2020/">2020</a></li>
<li><a href="https://simonwillison.net/2021/">2021</a></li>
<li><a href="https://simonwillison.net/2022/">2022</a></li>
<li><a href="https://simonwillison.net/2023/">2023</a></li>
<li><a href="https://simonwillison.net/2024/">2024</a></li>
<li><a href="https://simonwillison.net/2025/">2025</a></li>
<li><a href="https://simonwillison.net/2026/">2026</a></li>
<li>
</li></ul></div>]]></description>
      <link>https://simonwillison.net/guides/agentic-engineering-patterns/</link>
      <guid>https://simonwillison.net/guides/agentic-engineering-patterns/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How to win a best paper award (or, an opinionated take on how to do important research)]]></title>
      <description><![CDATA[How to win a best paper award (or, an opinionated take on how to do important research that matters)<div class="inner"><p>At <a href="https://eurocrypt.iacr.org/2025/">EuroCrypt</a> last <span class="c1">week</span> <span class="c1">month</span> year<a href="#footnote1"></a><label for="foot">[a]</label>Yes, it did take me eight months to write this blog post. I am slow at writing. I was honored to receive a best paper award for <a href="https://eprint.iacr.org/2024/1580">a model stealing paper</a> I wrote with my co-authors Jorge Chávez-Saab, Anna Hambitzer, Francisco Rodríguez-Henríquez, and Adi Shamir. While there, a few people asked what I do differently to win awards like this. I told them what I tell everyone: honestly I don't really know and it's mostly just luck. And while I do think this is true to a large extent (whether any particular paper wins an award is mostly luck), it's clearly not all down to luck, and I thought I actually owe it to others to give a more actionable response. So this is my attempt at that.</p><p>More generally, this article covers my process (for my field! yours may differ.), and gives an opinionated perspective on how research should be performed, and how papers should be written. I'll break this post out into roughly four sections:</p><ol><li>coming up with a good <a href="#idea">research idea</a></li>
<li>performing good <a href="#doing">technical research</a></li>
<li><a href="#writing">writing</a> understandable and compelling papers</li>
<li>... and then what happens <a href="#after">afterwards</a></li>
</ol><h3 id="idea">Coming up with your best-paper-worthy idea</h3><h4 id="taste">Have good taste for problems</h4><p>The single most important skill to develop for high-impact research is good taste in what problems are worth solving. If you have good taste, and you keep writing papers, eventually you'll write one with exceptionally high impact. But if you have bad taste, you could write a hundred papers and never do anything of consequence.</p><p>Researchers who have developed good taste find clever and elegant approaches, and find themselves pulled toward solutions that feel "right" before they can fully articulate why. At a macro scale, they pick problems that will matter; at a micro scale, they take approaches likely to succeed. And perhaps most importantly, they make these decisions early, before wasting months of effort.</p><p>People who haven't refined their taste frequently spend months on problems that don't matter, or take approaches doomed from the start. They write papers that are technically correct but that no one reads, because they never asked whether the question was worth answering.</p><p>Unfortunately, teaching taste is hard. What makes an excellent PhD advisor is someone who has learned to teach this---and that's not me. But if I had to summarize it in one sentence, it would be that taste comes from practicing the skill of research, keeping your focus always on identifying what works and what doesn't.</p><p>In slightly more detail, continue reading the rest of this section, which will discuss everything that I think is worth doing to refine your sense of taste, and to put yourself in a position where good ideas will find you.</p><h4 id="collaborators">Have great collaborators</h4><p>No one does science in isolation. The only way to get anything done is to build on the ideas of others, and having <em>others</em> to work with helps immensely.</p><p>Good collaborators do more than give you someone to offload work onto. They catch your mistakes before someone else does. They push back on bad ideas so you don't waste time. They bring skills you don't have. And they give you someone to bounce ideas off, to figure out what you should be doing in the first place.</p><p>Saying "have great collaborators" is not very actionable. And that's mostly by necessity: there is no one step that gets you great collaborators. But you have more control over this than most things in life. Research is extremely amenable to collaborations that span the world.</p><p>Almost all researchers are trying to write great papers; if you have an idea they could help with, you'd be surprised how often a simple email works: "Hi [person], I am working on [project] and have done [steps 1-3]. I am now working on [problem] and believe [your work] would help. Would you be open to meeting to discuss?" Or, another format, "Hi [person], I saw that in your [paper] you proposed [problem]. I have solved [steps 1-3] and believe that with your help we could address [step 4,5]. Would you be open to meeting to discuss?"</p><p>For instance, <a href="https://eprint.iacr.org/2024/1580">the EuroCrypt paper that prompted this article</a> happened because Adi was giving a talk at Stanford on <a href="https://eprint.iacr.org/2023/1526">his 2023 paper</a>, itself an extension of <a href="https://arxiv.org/abs/2003.04884">one I wrote in 2020</a>. I had never worked with him before, but after the talk I asked whether it would be possible to extend the work in a particular direction. He said he didn't know how, but thought it would be interesting. So I spent the next 12 hours working out a partial solution, and sent him an email with what I'd found, asking if he had ideas for how to proceed. He did, and that became our 2025 paper. (Please note, I'm not suggesting "just email a Turing award winner" as a general strategy, but rather, if you email someone a solution to a problem they appear interested in, you're far more likely to get a reply (or even a paper) than if you just send an email "I love your work can we collaborate". The probability someone will respond to you increases dramatically with the amount of time you put into sending it.)</p><p>As another instance of this happening in reverse, in 2017 Anish Athalye emailed me asking me to break a paper he was working on for ICLR'18. I broke it, and we realized the attack was general enough that we should write a paper on it. So we broke the other ICLR'18 papers with a generalization of this attack, which became <a href="https://arxiv.org/abs/1802.00420">our ICML'18 paper</a>.</p><p>Cold emails aren't the only way to find collaborators. The best use of conferences is to find people who like similar problems and just talk to them. If something comes up, great, you've got a collaborator. Or you'll have worked with X for a while, they'll have worked with Y, and X invites you and Y to work together. Broadly, just being around, available, and having interesting ideas you're willing to discuss is an easy way to find collaborators.</p><p>(I say "interesting ideas <em>you're willing to discuss</em>", because many people keep their ideas close to their chest as if someone else will steal them. I think this is generally not worth worrying about: ideas are cheap; execution is hard. Most researchers already have far more ideas than time to pursue them, so whoever you're talking to almost certainly won't drop everything to scoop you. And even if they did, they probably wouldn't execute as well as you---you've been thinking about it longer and have enough of a head start they'd be wasting their time. So share your ideas more freely! I do.)</p><p>Okay, so you have a team to complement your skills and make up for your deficiencies. The next step is to learn from everyone you're <em>not</em> working with. Fortunately, this is easy: the entire reason we publish papers is to teach the scientific community something new. So all you have to do to gather the wisdom of everyone in the world is read as much of the literature as you possibly can. You can't build on the body of scientific knowledge without knowing what that knowledge is.</p><p>This can feel daunting, especially when your research area is large. I'm sure entire books have been written on how to read papers efficiently. But in a few words: I try to be very intentional about <em>why</em> I'm reading any given paper, and typically have one of three mindsets:</p><ul><li><strong>To get a sense of what is possible.</strong> For most papers I "read" I'm just keeping up with what's known, and the only thing I hope to take away is (1) is this paper useful, and if so, (2) what's the new thing that makes it useful. In a good paper this is answerable in a sentence: your goal is to find that sentence. (As a writer, your job is to make that sentence easy to find.)</li>
<li><strong>To understand what you have to do to achieve some result.</strong> If a paper is related to your work, read it more carefully. You still don't need to understand every last detail, but you should read the pieces you need in enough depth that you understand that one aspect of the paper. Maybe they used a clever proof technique, or their experimental setup is particularly elegant, or they introduce a new algorithm you're going to use. Extract what you need without getting bogged down in the rest.</li>
<li><strong>To extend upon the paper.</strong> For a very small fraction of papers---a few each month---I do actually read the full paper top-to-bottom and think critically about every sentence. Here you're looking to understand everything well enough that you could, without referring back to it, reproduce the work. This helps you answer: what implicit assumptions did they make? What did they leave for future work? What errors did they make?</li>
</ul><p>For example, one of the papers I'm most proud of is my <a href="https://arxiv.org/abs/2112.03570">membership inference paper</a>. When I started reading that literature, very little of it made sense to me---the attacks seemed confused and overcomplicated, training neural networks on the output of models in weird ways that made no sense to me. The evaluation metrics were weird too. The paper I eventually wrote argued the field should use a much simpler approach---treating membership inference as the hypothesis test it actually is---and evaluate using a different metric. A few years on, that's what everyone does. But I couldn't have made that correction without reading everything first, so I could target my argument to land. You can't fix what you don't understand.</p><p>Now here's an apparent contradiction. Once you've read everything, the second step is to forget it all. The reason is simple: everything that's already been done has already been done. If you constrain yourself to thinking only about what's been done, you'll never come up with something clever and new.</p><p>It's especially important not to get swayed by bad ideas---it's a bit taboo to say, but every field has them. These are directions where someone (usually someone famous!) published an influential paper that got something critical wrong with the approach, methodology, or evaluation... and then the rest of the field followed along the same wrong direction without thinking critically about the initial choice, because that's just how the field does things.</p><p>Another way this can happen is that, when a research area is young, an early paper makes some arbitrary decision that was never well justified (and the author knew it!) in a rush to publish. Then everyone else just goes along with this bad idea for far longer than they should. If you pay too much attention to how the field does things, it's easy to subconsciously accept these bad ideas as good.</p><p>Another reason ignoring the literature can be helpful is that sometimes a bunch of work tries to solve some problem, and so everyone assumes it must be hard---just because no one has solved it yet, even though no one has really tried a fundamentally different approach.</p><p>The final failure mode is that, once you've read a bad idea, it's hard not to let it poison your thoughts. Once you've seen ten papers use Approach X, you implicitly assume Approach X is the right way, even if it's not.</p><p>Again, back to the membership inference paper. When I first saw the early papers, I thought "that's a nice idea; but nothing about these methods makes sense" and so I put out of my mind how they worked and didn't touch the field. Only after I saw <a href="https://arxiv.org/abs/2008.03703">a paper that gave me an idea</a> for how to do membership inference in a way that made sense did I (1) develop my own attack, and then (2) read what everyone else was doing. The ordering here---doing the work first---helped me not get distracted by the wrong approach. (Of course, you have to be careful when doing this! You don't want to spend months re-inventing what already exists, or worse, re-inventing wrong ideas people have discarded.)</p><h4 id="pick-impact">Pick your ideas for impact</h4><p>Some people go into research with the objective of writing a conference paper. Don't do that. You need to go into research with the objective of discovering something interesting, important, and new. The paper follows as a natural consequence.</p><p>High impact research does not come from the goal of being adequate. You can't ask “what is the minimal contribution I can write that will technically still count as a science paper?” You're doomed to fail at having high impact if you take this approach. Or, maybe, you're doomed to succeed at your goal---writing mediocre papers with little reason to exist.</p><p>(It's a sad truth that marginal and boring papers are more likely to be accepted than ones that do something truly interesting. But you'll never write an important paper that way. Learn early to have a thick skin; accept your rejections.)</p><p><a href="https://www.cs.virginia.edu/~robins/YouAndYourResearch.html">Hamming was famous for asking</a> "what's the most important problem in your field, and why aren't you working on it?" Approach your research with this mindset. One excellent paper is worth a thousand mediocre ones, and takes less time to write.</p><p>This doesn't mean every paper you write has to have grand ambitions. Sometimes you don't know what the best paper to write is. Sadly---at least for me---<em>sit around and hope for inspiration</em> isn't a valid approach to coming up with important ideas. At some point the marginal hour spent trying to find a good idea is less valuable than just working on ... anything. So when you don't have a hugely important idea, it's entirely reasonable to just write something to practice your craft. In any year I usually have one or two papers that I really think have the potential to be great. The rest I write because writing good-enough papers is what helps me discover the ideas that lead to important ones.</p><h4 id="only-you">Do something only you can do</h4><p>Try to do something only you can do. Find a paper that someone else won't be submitting to the same conference. Because if all you're doing is something someone else would have done, have you really contributed anything at all?</p><p>To be clear, there's a spectrum here. Some people have ideas no one else would have come up with in a lifetime. They're all famous, have already won their Nobel Prize, and aren't you or me.</p><p>Everyone else has to settle for peering a few months further into the future than others could manage. All ideas are waiting to be found, and within a few years, anything you find would have been found by someone else anyway. So the magnitude of your contribution is judged, in a very real sense, by counting the months between when you publish, and when the next person would have. Try to pick something that would have taken at least a few months for someone else to do as well as you did.</p><p>Something subtle that's hard to appreciate is that if you write a high-quality paper early, you can have an outsized impact compared to writing that same paper even a year later. People settle on "how things are done" early, and altering the direction of a field is much harder than starting it in the right direction. So especially when fields are young, writing something six months earlier can be exceptionally valuable if those six months help shift the community towards the correct framing of the problem.</p><p>How do you know when you have something only you can do? I look for areas where, when I read the work, I want to scream. Areas where you keep asking yourself "why is everyone doing this obviously wrong?"</p><h4 id="best-in-world">Find your comparative advantage</h4><p>It's also helpful to discover along which dimensions you have a comparative advantage. In mathematics, Gowers writes that mathematicians <a href="https://www.dpmms.cam.ac.uk/~wtg10/2cultures.pdf">are either "theory-builders" or "problem-solvers"</a>; the former is more interested in developing theories of how math works, while the latter just wants to prove (or disprove) statements. Both are necessary to advance the field, but any individual might be better suited to one than the other.</p><p>Fortunately there's not just one direction of variance, and the space of variables differs between research areas. Because this space is high-dimensional, it's highly likely you are the best in the world at some specific corner of it. Find that corner.</p><p>As an example: I'm not very good at proposing entirely new research directions. I've never written papers proposing entirely new directions, or developed completely new strategies for approaching a problem. But I am reasonably competent at taking a fuzzy field someone else defined, and bringing clarity and order to how things should be done. I'm not the first to pose the problem of adversarial examples, but I laid the groundwork for <a href="https://arxiv.org/abs/1902.06705">how to properly evaluate adversarial robustness</a>. I'm not the first to show that language models can memorize training data, but I showed it <a href="https://arxiv.org/abs/2012.07805">in a much more visceral way</a> than anyone else. Once a field has matured, I'm less good at doing the rigorous science necessary to drive things forward, so I move on to something new.</p><p>There are plenty of other directions of variance. Another thing I've done a bunch is to take ideas from distant fields and bring them together. Model stealing existed in the machine learning community since 2016; I found a connection to differential cryptanalysis that resulted in a series of papers, including the EuroCrypt'25 paper that inspired this article. Or a few years back I helped write a few papers (<a href="https://arxiv.org/abs/1905.02249">MixMatch</a>, <a href="https://arxiv.org/abs/2001.07685">FixMatch</a>) that developed improved semi-supervised learning methods. I observed that because semi-supervised methods train on large unlabeled datasets, adversaries might be able to poison that data more easily; and so I turned this idea into a paper that received <a href="https://arxiv.org/abs/2105.01622">a Distinguished Paper Award at USENIX Security 2021</a>.</p><p>You should try to figure out where you have your differential advantage. There are probably three or four ways that I've found I can combine my skills that other people seem to find challenging. Not every problem needs to be one you're uniquely positioned to solve, but keep an eye out for when one comes along.</p><h4 id="lucky-idea">Get lucky: you happen upon a good idea</h4><p>But above all else, the most important thing here is to get lucky.</p><p>I'm one of those people who sees research as not unlike being an early explorer. You have some control of the situation: if you see a lush forest in one direction and a barren desert in the other, you probably shouldn't head into the desert without reason. But sometimes, from where you sit, there are two equally good options and you're forced to just pick one. One may lead to wonders; the other to a cliff edge with nothing interesting to be found. You can't know which is which in advance, and you just hope you choose right. (Having good "research taste" is what helps you predict how fruitful a path will be before you explore it.)</p><p>Half the papers I've written weren't from some deliberate thought process, but from a spontaneous conversation, or because I was thinking about some problem when I happened to read a paper that introduced a tool I could use. You can do everything right, and for reasons entirely outside your control, not end up with excellent ideas.</p><p>This isn't to say it's all luck (the last several sections were dedicated to the ways in which it's not), but no one can deny there's a lot of luck here. Fortunately, as has been said a million times, you still have to take advantage of luck when it finds you, and that takes practice.</p><p>As an example, I wrote <a href="https://arxiv.org/abs/2302.10149">a paper a few years ago on poisoning web-scale training datasets</a>: we showed it's trivial in practice to get malicious text into the largest vision- or language-model datasets by modifying a small amount of content on the Internet. I didn't go "looking" for this paper; I wasn't trying to come up with a practical poisoning attack. I had just written two papers on model poisoning in the <a href="https://arxiv.org/abs/2105.01622">semi-</a> and <a href="https://arxiv.org/abs/2106.09667">un-supervised</a> setting, came across the <a href="https://laion.ai/laion-5b-a-new-era-of-open-large-scale-multi-modal-datasets/">LAION-5b</a> dataset, wanted to study it, and noticed an attack I could mount. (Namely: buy expired domain names for images in the dataset.) There was some skill here---I had to notice the attack was possible---but everything really just fell in front of me.</p><h4 id="lucky-suited">Get lucky: you're well suited to solve important problems</h4><p>Let me talk about another aspect of luck that I think goes under-appreciated.</p><p>Some problem areas are just more important than others given the current state of scientific knowledge. Take the world's most capable programmer and drop them in 1600s Europe and their skills would not be very useful. Take the best blacksmith from the 1600s and bring them to today and they're not going to have much impact on science or the world. And this is through no fault of their own---at any moment in time, certain skills are on the critical path of scientific discovery.</p><p>This is true not only at the level of entire careers (blacksmithing vs programming) but also of individual problems within a research area. For example: I am probably the world expert on breaking defenses to adversarial examples in the image domain. Through a confluence of lucky decisions, I got pretty good at that. A decade ago when the world needed people who could do this, that skill got me a few best paper awards. But today, despite being a better breaker-of-adversarial-example-defenses than I was a decade ago, I'm not going to win any more awards for it because the world doesn't need any more image adversarial example attack papers. That field has been thoroughly explored, and new directions need exploring.</p><p>What does this mean for you? Two things. First, unfortunately, if you're excited about and skilled at a topic other researchers don't see as important, you'll have a harder time getting recognized. But second, fortunately, if you're in an area that's not the "hot" one, you'll have a much easier time standing out.</p><p>This isn't to say you shouldn't do work that's not viewed as "important" by the world at this moment. I feel pretty strongly that your overall impact is the product of your skill in some area, multiplied by how important that area is. If you're very good at a less "important" problem, you'll contribute more than working on something you're not very good at.</p><p>I got particularly lucky ending up on the critical path for adversarial machine learning: I spent the first few years researching computer security doing fairly mundane things. The papers I wrote were important enough and got a few hundred citations each, but they weren't going to fundamentally change the research landscape. But then machine learning started becoming increasingly important, and I found myself one of the few security researchers now studying machine learning. As machine learning kept getting more important, so did my work.</p><p>At some point this field will taper off, and then I'll no longer be lucky in this way. I'll keep working on these problems because I find them fun, but it will be someone else's turn to get lucky that their life decisions led them to where the problems they're uniquely positioned to solve are the ones other researchers consider most important.</p><p>(Given this, what makes a truly great researcher is someone who has re-invented themselves and solved important problems in one area and then, after the world changes, became someone who could solve them in another. I have no idea how to do that---I've never had to. But people who have done this impress me far more than one-hit-wonders.)</p><h3 id="doing">While doing the best-paper-worthy research</h3><p>Great! You've found an idea that's worthy of a best paper award. It's an important problem, you have some critical insight that's novel, and you think you have a path to completion. Now you have to execute on it flawlessly.</p><h4 id="lucky-doing">Get lucky</h4><p>But first, let's pick up where we left off. There's going to be a lot of luck on this step too. Most ideas that sound really good die when they make contact with reality. You can't predict what will or won't work ahead of time (that's what separates science from engineering), so you have to get lucky that the idea you're trying will actually work.</p><p>I can't tell you how many ideas I've had that in any just world would have been amazing, but ultimately didn't work out. The best thing here is to accept that not every idea you come up with will work, and come to terms with the fact that what works and what doesn't is mostly out of your hands. There's something to be said for really going all-out and trying your best to make something possible, but trying harder won't let you prove a statement that's false.</p><h4 id="kill-not-working">Kill papers that are not working</h4><p>Because of the luck in which ideas work out and which don't, you need to work on many potential ideas to find the ones that work. Almost all good papers have a degree of risk to them: if it was obviously going to succeed someone else would have done it already. So it's important to try many ideas, and you can only do this by <em>not</em> working on bad ones.</p><p>I start probably five times as many papers as I finish, and each of them I thought was a good idea that had merit, but things just didn't work out as I expected. The best way I've found to minimize wasted time is to start with the sub-problem most likely to fail. It's comforting to work on the parts of a problem you know how to solve, but this teaches you nothing about whether your idea is any good. You want to de-risk the project as quickly as possible.</p><p>In this way, writing a paper is a lot like forming a start-up. Fail fast applies just as well here: don't build the polished version of your experiment when a small prototype will tell you whether the core idea works. If the prototype shows promise, clean it up later. If it doesn't, you've saved yourself months.</p><h4 id="kill-low-impact">Kill papers that end up having low impact</h4><p>As Stephen King says: <a href="https://en.wikipedia.org/wiki/On_Writing:_A_Memoir_of_the_Craft">"kill your darlings."</a> Let's say you've just spent a month developing an idea that's "working" insofar as the technical contributions are there, and the results are trending positive, but it's just not working out as you hoped. You could probably, with some work, turn this into a paper. But it's not going to become a <em>good</em> paper. When this happens, just kill the idea and pick something new. Maybe turn it into a workshop paper or a blog post. Still try to get some value out of it. But don't waste your time.</p><h4 id="reprioritize">Re-prioritize projects ruthlessly</h4><p>Finally, sometimes you have to kill papers not because there's anything wrong with the one you're working on, but because something else comes along that's even higher impact. When this happens, don't fall into a sunk cost fallacy; pivot immediately to the more important paper. This is <em>"it's not you, it's me"</em> applied to research. (Because the impact of papers is distributed exponentially, even if you're 90% of the way through a "just ok" paper, the marginal return on spending the last 10% to finish it versus spending that same 10% on a paper 100x more important makes the latter the clear winner. And some papers truly are 100x more important than others.)</p><p>You have to be careful with this advice, though. For one, it requires accurately assessing the impact of a paper before it's done, which is remarkably hard. But even if you have excellent taste in problems, new ideas always sound more exciting than ones you've been working on for a few months, so it's easy to get distracted by some shiny new problem just because it's new.</p><p>As an example, I was in the middle of a few other pretty interesting papers when GPT-2 came out, and I realized this was probably something important to study. Instead of continuing with whatever I was doing, I just dropped that work on the ground (I don't even remember what it was anymore) and started looking at these new language models. (I guess that turned out to be the right decision, and in hindsight I probably should have pivoted harder and earlier.)</p><h4 id="unreasonable-effort">Put in an unreasonable amount of effort</h4><p><em>"Sometimes magic is just someone spending more time on something than anyone else might reasonably expect."</em> -Teller, of Penn and Teller</p><p>The same is true for research papers.</p><p>Great papers don't have poorly performed experiments. Part of doing high quality science is not only that you've got a really good idea, but that you went to unreasonable lengths to execute on it better than anyone would reasonably expect.</p><p>Every experiment should be as precisely performed as you can manage. Run multiple trials. Control for confounders. If there's a question a skeptical reader might ask about your setup, run the experiment that answers it before they ask. On multiple occasions I've put in several hours of work just to strengthen a "sometimes" to "usually", because this is what it means to care.</p><p>Earlier I made an analogy to being an explorer; here's another I like even more. Think of yourself as a wildlife photographer. Obviously you need to be in the right place (you won't get a great picture of anything from your couch) and you need to be skilled at your craft. But once you've met those preconditions, the way to get the best picture is to just spend an unreasonable amount of time waiting for exactly the right circumstances to arise.</p><h4 id="focus-doing">Have focus</h4><p>Remember that the goal of a paper is to advance a single idea. This idea can take many forms, and it should be expressible in as few words as possible. I find it useful to actually write down this idea somewhere well before I start writing the paper, so I don't forget what I'm trying to do.</p><p>Every experiment should connect to the core idea. Every paragraph and every figure you'll eventually write should be directly attributable to the goal of the paper. (Have I mentioned it's important to have a singular focus? You should.)</p><p>Because the objective of the scientific process is to understand what's true about the world, a common trap is trying to run every possible experiment that relates to your new idea. This doesn't work. First, if you actually tried everything, you'd never do anything else. But also this will just distract from your key idea. Readers will forget why you're doing whatever you're doing, and lose track of the core idea. On occasion you have to do this (e.g., because a reviewer requires it), and then you must be careful to bring back the reader's focus at the earliest possible opportunity.</p><h4 id="maximal">The paper should be the "maximal" version of the paper</h4><p>Counterbalancing the above, make sure the paper you're writing doesn't have obvious improvements you didn't do. That is: your paper should be at a local optimum; the reader must not be left with the thought "I really wish the authors had done X; that would have been an obvious improvement."</p><p>Put differently, when the reader is finished, they should feel satisfied as if they'd just finished an expensive meal. Sure, maybe they thought the portions were a bit small, or would have enjoyed a third appetizer. Everyone wants something different; you can't satisfy every preference. But they shouldn't feel like something essential was missing. And they certainly shouldn't feel like something was spoiled.</p><p>In your papers, this means that you shouldn't leave obvious questions unanswered. If you propose a method that obviously could be applied to domain X, then you should do that. If your result implies some trivial lemmas, you should discuss those. If there's some critique that you expect many people may have, you should address that.</p><p>But don't go too far; to extend the metaphor: it's okay to leave room for dessert. Having small improvements left over is actually a good thing, because it gives someone who's finished reading your paper a way to engage with it further. If you introduce a new tool with various applications, leaving open a few interesting (but not critical) directions makes space for others to pick up your ideas and work on them, expanding the number of people working on this new topic you presumably care about.</p><h3 id="writing">When writing down the best-paper-worthy research</h3><p>You've finished your research, and all the experiments turned out exactly as you wanted. It's time to write things down. If you're hoping for a best paper award, this is one of the most important steps: most papers are written poorly, so you need to actually write yours well.</p><p>But even if you're not hoping for a best paper, most people only read a few papers on any given topic. Yours doesn't have to be the most technically sophisticated---someone else will design a better algorithm in a few years anyway---what really makes a difference in how often people read your paper is how easy it is to read and how approachable it makes your field.</p><p>One of the papers I think I did the best job writing was a paper I discussed above on membership inference attacks. My goal with this paper was to try and change the way the field studied the problem, and so I spent much more time writing than I normally do. When we wrote it, our method was state-of-the-art. But so is the method in every paper when it's first written. The reason this paper has been cited so frequently over the last few years is that we did a far better job writing down what a membership inference attack is than anyone had done before. So even though our exact method no longer really matters, the fact that our paper is approachable and readable means it's now one of the canonical papers people point to for this field, and so it's had an exceptionally high impact.</p><p>So in this section I'll tell you what I do to make my papers accessible and informative.</p><p>This is the part (1) I feel the least qualified to write, and yet (2) feel the need to write the most. As someone who got C's in high school English and had to take remedial writing classes my freshman year of college, writing well does not come naturally to me. But in some sense I'm also better positioned to write this section than the last two. I've never really struggled with programming. I don't know what it means to be someone who isn't good at it and had to teach themselves to be better. But I do know what it means to be bad at writing, and I do know it's possible to become someone who's better at it.</p><h4 id="focus-writing">Have focus</h4><p>Earlier I told you to have focus when performing your experiments. Now I'm going to tell you to have focus when writing them down.</p><p>Research papers should have exactly one idea. You're allowed to support this idea through multiple experiments, and you're allowed extensions. But you should have One Singular Idea. Everything you write should connect to it. (Yes, even the background! I'll talk about this later.)</p><p>Usually this is easy: if you've developed a new algorithm or evaluation method, that's your one idea. But occasionally you have many ideas you'd like to communicate, and having focus means you get to pick only one. If you try to communicate all of them, the reader will remember none.</p><p>Yes, this is annoying. I wish it weren't true. But it is. The sooner you come to terms with it the better.</p><h4 id="know-reader">Know your reader</h4><p>It's an unfortunate truth that, once you've written a paper, you can't tailor the text to every person who might want to understand what you've done. You have to pick a particular reader in mind, and write for that person.</p><p>This lets you write a useful introduction (what do they need to hear to be motivated to read your paper), background (what do you need to teach them that they don't already know), methods (how does this build on ideas they've seen), and conclusion (what should they take away).</p><p>(Incidentally, the purpose of a background section is to broaden the scope of who "the reader" is. Initially the reader might be anyone, but after the background section, you can assume they're someone familiar with everything you've written there. This should help you write a useful background that's not just a block of citations to appease reviewers.)</p><p>Personally I've found the best person to write for is the six-month-younger version of myself. What would I have needed to say to explain why this idea was a good one to myself-before-I-had-it? Why does this paper have a chance of succeeding? Why is this design the right one?</p><p>It's more challenging when the reader you have in mind is not yourself. Sometimes, for example, I write papers as an argument to convince someone to change their mind. In this case, I need to write towards that person. When doing this, I find the best approach is just to share your paper with someone you imagine is your ideal reader, and get their impression.</p><h4 id="title">Don't obsess over your title</h4><p>Hot take. I know. But I don't think your paper title matters if your paper is good. In a world of clickbait, I think it's refreshing that, in science, we live in a world where as long as your title is accurate you'll be fine. Remember: we're trying to do good science, not accumulate citations we don't deserve because we titled our paper something overly broad. All you need to do is make sure that your work will be seen by the researchers who need to see it.</p><p>This doesn't mean you can ignore the title. For every hundred people who read your paper's title, one will read its content, and so you should accurately describe your work, and let people know what to expect. But don't feel like you have to clickbait "TEN THINGS GRADIENT FLOWS CAN DO. NUMBER SEVEN WILL AMAZE YOU!"</p><p>If you're struggling to write a good title, it's also a good sign that your paper is trying to do more than just one thing. If this is the case, fix the cause, not the symptom. Then title your paper appropriately.</p><h4 id="abstract">Your abstract does matter</h4><p>The purpose of the abstract is to, in just a few sentences, simultaneously (1) convey the entirety of your paper, and (2) convince someone to read it if it's related to their work. This is hard. I frequently rewrite abstracts four or five times before finding one that I like, and even more frequently end up without anything I like at all.</p><p>After briefly reviewing some of my most important papers, it (empirically) looks like I actually have a pretty formulaic abstract structure: in sentence (1) what topic you're working on, and then in sentence (2) explain what problem you're going to solve in that field; sentence (3) should say something about your results or methods, and sentence (4) should say something about whichever sentence (3) didn't; and finally sentence (5) should say something about why your work matters. This is, I think, generally a good structure. The second most frequent way I write abstracts (again, empirically) is to go (1) claim of some new result, (2) evidence for this claim, e.g., method or data, (3) impact of this result. This is what I do when the topic is already very broad (and so stating it isn't important), or the paper is meant for only a very specific audience.</p><p>Your abstract should be specific and explain exactly what you're going to get out of your paper. Of my favorite papers, the abstract for every one has at least one specific number to highlight what I've done: "we consider problem X" is far less useful than actually stating your result. Similarly, don't hedge: just state the clean (but true) version of your result; everyone knows you have only a few sentences here.</p><p>Finally, your abstract should convey a sense of importance. This can either be in the problem you've selected, the novel method you've developed, or some big lesson you hope people take away. Make it obvious what you think is important, and focus in on that.</p><p>An introduction is the beginning of a story. You start by meeting the reader where they are---with what they currently believe to be true. Then you guide them into the world where your paper is set, where your ideas make sense. And finally you explain, in this world, your contribution.</p><p>The reason you have to do it this way is that an idea can only land if the reader is in the right frame of mind to receive it. You're communicating with busy, skeptical people who are suspicious of everything new. You can't just state your idea and expect it to work; you have to help the reader get to the point where they're ready to hear what you have to say.</p><p>Sometimes this is easy. If you're introducing a new technique in a well-studied area, you just need to say "We solve X unsolved problem" and that's enough. You don't need to tell a story because it's a story everyone already believes. Sometimes it requires a little work. If the problem is one people mostly know but might not be fresh in their mind, it's probably enough to remind them for a paragraph or two, and then dive in.</p><p>But sometimes this is hard. If you're working on a problem not yet well studied (which will be the case for most best-paper-worthy research), you'll need to spend enough time introducing the setting, the cast of characters, and the backstory that the reader can appreciate what you're about to do. (At the same time, you can't spend six pages writing a novel before getting to the action. Readers have short attention spans, and you have at most two pages.)</p><p>For example, one of the hardest introductions I had to write was for <a href="https://arxiv.org/abs/2003.04884">a paper I submitted to Crypto in 2020</a> about stealing the weights of a neural network. Crypto, if you're not familiar, is where people submit mostly theoretical ideas in cryptography. It does not usually accept machine learning papers. So I spent three pages easing the reader---a theoretical cryptographer---from their world into mine. Those three pages were the most important pages of the entire paper. If I could convince them that model stealing was actually comparative cryptanalysis in disguise, I'd have done my job. If not, nothing about my methods or the strength of my results would save me.</p><p>Another case where introductions are hard is when you're writing about a problem that doesn't quite exist yet but will soon. In <a href="https://arxiv.org/abs/2105.01622">my semi-supervised learning paper</a>, I was arguing that poisoning unlabeled training data was going to become a serious threat---but in 2020, training on huge uncurated unlabeled datasets wasn't yet standard practice. So a good chunk of the introduction was spent arguing not about my attack, but about where machine learning was heading: everyone was about to start training on exactly the kind of data my attack targets. I had to sell the reader on the future before I could sell them on the paper.</p><p>And in the most challenging cases, you can't state your idea outright at all, or it'll be dismissed as heresy. Here the reader has to arrive at the conclusion themselves; your job is to lay out the evidence in an order that makes the conclusion unavoidable.</p><p>For example, several years ago I drafted a paper <a href="https://arxiv.org/abs/1902.06705">"On Evaluating Adversarial Robustness"</a>. In one sense, a single sentence could describe this paper: "Here is a protocol you can follow to make sure you've evaluated adversarial robustness correctly." But this is not the idea I wanted to convey; it's not <em>why this paper exists</em>. The idea I actually wanted to convey was: "evaluating adversarial robustness is hard; almost everyone gets it wrong, and you probably will too." But speaking these fifteen words to someone does not make them enlightened---they have to feel it in their bones. And if I'd just said it outright in the intro, the reader's immediate reaction would have been "well, not me," and I'd have lost them before I started. So the job of the paper was to provide evidence so overwhelming that by the end, the reader arrives at that conclusion on their own.</p><h4 id="figures">Each figure must stand on its own</h4><p>Some readers will study your paper top-down. But most will skim for the important details, as I recommend you do when deciding if a paper is worth reading. So you must make sure the reader can quickly tell if your paper is worth reading. And the best way to do this in my area of experimental computer science is to have self-contained figures that explain the main points of your story. For example, Figure 1 may explain the problem; Figure 2 explains your algorithm; Figures 3-4 explain details of your method; Figures 5-8 have your results and analysis. Importantly, each figure can be interpreted on its own without having read the text.</p><p>If it's obvious what you're showing then this is easy: just state the interpretation. "Figure 7. Our method performs 3% better than all prior methods" works well for a bar graph showing accuracy for your method versus three others. But other figures will need explaining; you must do this. If your figure can't be explained in a caption it is too complicated. Split it into multiple figures. If it doesn't have a single sentence describing the takeaway, it is also too complicated.</p><h4 id="write-conclusion">Write a good conclusion</h4><p>Now that you've finished your paper, it's time to wrap up. Which usually means you write a conclusion.<a href="#footnote3"></a><label for="foot">[b]</label>In some fields you don't. In my field you do. In my experience, the conclusion is usually the worst part of most papers I read. Conclusions are not abstracts or introductions in the past tense.</p><p>Let me repeat that: CONCLUSIONS ARE NOT ABSTRACTS OR INTRODUCTIONS IN THE PAST TENSE.</p><p>Instead, the purpose of a conclusion is to provide a moment of reflection.<a href="#footnote4"></a><label for="foot">[c]</label>In a good paper you should be doing this throughout, wherever appropriate. This helps keep the paper interesting, and makes it easier to write a conclusion where you can assume the reader has already done some reflecting on your ideas. Explain to someone who has just spent the last hour immersed in the technical details of your paper what important idea you want them to take away. Part of this will---necessarily---involve reminding them about some of the facts you told them earlier. If you introduced some new fancy method in Section 2 and then spent sections 3, 4, and 5 evaluating it, you'll want to remind the reader you had a new method. After all, that's part of the important lesson of your paper. But your reminder should be brief. As quickly as possible, return to the primary focus: answering the question "so what?"</p><p>If your paper is important, the answer to "so what?" should be more than "our method makes the number go up by 2%". If that's all you can say, then I'm sorry, you may have valuable science, but you don't have something that's going to win any awards. (In fact, something I frequently do when deciding if a paper is worth writing is write my best-case conclusion before even performing the research. I ask: if this paper were to succeed wildly---if all the experiments turned out exactly as I want---what could I say in a conclusion? If I have nothing to say beyond repeating the results, then what I've done mustn't have mattered very much. And so I'll just drop the project and move on to something else.)</p><p>In the story analogy above, your conclusion is when you break the fourth wall and just straight up tell your reader the moral. Be heavy handed; leave nothing unsaid.</p><h4 id="on-writing">On Writing</h4><p>There are thousands of books on how to write well. Read them, or don't. The only rule that matters is delivering the message to your reader; all other rules come second. Remember, though, that the reader won't receive your message if they're so bored with how you're saying things that they stop reading.</p><p>Fortunately, being not-bad at this is enough. As I'm sure you've noticed reading this article, I'm not some mystical word wizard who captures your imagination with every phrase. But research papers aren't graded for their prose; no one has won a Pulitzer for their science journal. As someone who isn't skilled at writing and used to be much worse, I've found the only way to get not-bad is to read more and write more.</p><p>If I were to briefly summarize the best writing advice I've received, it would be to listen to how your writing sounds spoken out loud, and try to make it understandable. I used to do this by reading my papers out loud to force myself to hear every word; I still do this sometimes, but now I also use text-to-speech systems to read the words back to me. You'll notice things you'd never have caught yourself.</p><p>Think about how what you write might be confusing to a reader. Pay particular attention to sentences that could have dual meanings, especially when one of those meanings is the wrong interpretation. Avoid sentences that lead the reader towards believing you're going to say one thing, and then saying something else. Make sure that the grammatical structure of your sentences places the impact on the words that matter.</p><p>Beyond that, remember that every rule can be broken. Long sentences are fine, as long as you give the reader time to breathe with some short ones after. You're allowed to use contractions, but don't overdo it. Think it would be helpful to ask a question? Go ahead. Don't use jargon in general, but do use it when the alternative is to be imprecise. Cut words and only write what's necessary, but don't be so terse your writing is unreadable or sounds jarring. Papers written in the passive voice are usually less understandable---but feel free to use it where appropriate (or funny).</p><p>Proofread your work. But your time is finite; every minute spent proofreading is a minute not spent doing something more important. Readers will forgive the occasional speeling mistake, repeated word, or or grammatical error, as long as they're rare and your message is well communicated.</p><h3 id="after">After writing the best-paper-worthy research</h3><h4 id="lucky-early">Get lucky: it's not "too early"</h4><p>It's easy for new ideas to be too early to be accepted. If you see the future before others do, frequently your work will be rejected because it assumes a premise others haven't yet accepted as true. So there's a lot of luck in when exactly you write your paper.</p><p>Again let me refer back to the paper I've mentioned a few times now on <a href="https://arxiv.org/abs/2105.01622">poisoning semi-supervised learning.</a> Unfortunately for me, semi-supervised learning had <em>just</em> begun to work in the last year. So when I submitted this paper to security conferences, it was summarily rejected several times because reviewers didn't believe it was worth studying. In their mind, semi-supervised learning didn't work and so attacking it didn't matter. After enough time had passed (and after four rolls of the dice) the idea that unlabeled data would play an important role in the future of machine learning became more widely accepted. And so my paper was accepted at USENIX Security and received a best paper award.</p><p>There are ways to mitigate being too early. Writing a compelling introduction that explains why your paper will become important in the coming years is helpful. You can also explain how your problem relates, even tangentially, to something real today. (But don't be deceptive about your true motivations.)</p><p>But sometimes there's nothing you can do. You write a paper, and it's fantastic. Ten years later it will be recognized as one of the most important ideas in the field. But at the time, no one (but you!) saw that yet. And that's fine. In some sense, this is the most rewarding type of paper to write. The one where no one believed in it or saw the value, but reluctantly came to understand it was right all along.</p><h4 id="lucky-hot">Get lucky: it's still a hot topic</h4><p>Most papers take a while from when you first come up with the idea to when they're finally published. And a lot can happen in a year---especially in my field of machine learning. You pick topics because they're important at the time and because you think they'll still be important in a year, but you can never be sure. You can try to mitigate this by being on the lookout for what might be important in the future. But this is very much a guessing game.</p><h4 id="lucky-first">Get lucky: no one else did it first</h4><p>Related to the above, you also need to get lucky that no one else writes the same paper and gets it published first. You can have done the most important research of the decade, but the nature of research is that whoever does it first gets a disproportionate share of the credit. This isn't how it should be, but it's how it is.</p><p>I've been on both ends of this more times than I can count---it's just part of life in research that good ideas are frequently discovered simultaneously. The body of scientific knowledge finally allows for some new idea to be discovered, and suddenly everyone is doing the same thing. There are ways to mitigate this---work on problems others aren't, spend time thinking about the future and not just the present, work quickly and efficiently---but you can only do so much.</p><h4 id="lucky-committee">Get lucky: the committee likes it</h4><p>Finally, you have to get lucky one more time: the award committee has to like your paper. At any conference, something like 2-10% of papers are truly excellent and deserving of recognition. But only a smaller fraction can receive an award. It's the job of the award committee to separate those that receive an award from those that merely deserve one, and then from this set pick one (or a few).</p><p>The way this happens differs in the details but is the same at a high level. First, your paper needs to get accepted. Then papers are usually filtered by the overall score of the reviewers, potentially informed by nominations from the program committee. This shortlist goes to an award committee. The award committee will usually filter this list down pretty aggressively if there are many papers, and deliberate at length about which paper should receive the award: your paper essentially goes through an entirely separate round of peer review. Finally, among all the papers sufficiently high quality that they probably deserve an award, one (or sometimes a few) are selected.</p><p>This means the specific people on the committee make a big difference. So you just have to get lucky that the committee likes your topic area, your problem formulation, and the way you've written your paper. Awards are frequently given for "political" reasons (e.g., to encourage more research in a particular direction, or to correct a particular misunderstanding of the community).</p><h4 id="persistent">Don't get discouraged; be persistent</h4><p>The majority of my papers that have received best paper awards were rejected at least once before they got in. In one case, a paper of mine was rejected four times first.</p><p>From what I can tell, this is normal. I think there's actually something going on to explain this: On the first pass, the paper is often rejected because it's saying something a little outside what's normally believed to be true. The reviewers aren't convinced and leave some confused remarks. Then, the authors (knowing they're right!) spend extra time revising their paper to make the arguments clearer and stronger, so even confused reviewers will understand it. The next reviewers (or the ones after that) see this paper a few months later---a stronger paper at a time when the idea is slightly less heretical. And then they give it an award.</p><h3 id="conclusion">Conclusion</h3><p>Good research (1) advances the body of scientific knowledge in a way that's (2) accurate and (3) approachable. Your job is to do all three. What I wrote above is, to a first approximation, the best way I know how to describe what I do, and what advice I'd give to others.</p><p>While I did title this blog post how to win a best paper award---and I do touch on this throughout---that's not why I wrote this article. As I hope I've made clear, a best paper award is one sample from a distribution. You don't control the sampling process---that's determined by, among others, the program committee, the timing of your work, who else submitted that year. But you <em>do</em> control the distribution. The award, if it comes, is just someone noticing where your distribution ended up. Focus on the distribution.</p><p>Because of this, you shouldn't go into research with the objective of winning a best paper award. It's unhealthy, counter-productive, and out of your control. But you also shouldn't go into research just trying to accumulate publications that don't matter. That's equally unhealthy, and even if you do achieve your goal you won't have done anything that mattered. Instead, write papers with the goal of having an impact. That's what matters, is entirely under your control, and is lots of fun.</p></div>if that's more of your thing.]]></description>
      <link>https://nicholas.carlini.com/writing/2026/how-to-win-a-best-paper-award.html</link>
      <guid>https://nicholas.carlini.com/writing/2026/how-to-win-a-best-paper-award.html</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Building a Procedural Hex Map with Wave Function Collapse]]></title>
      <description><![CDATA[<header>
<p class="tagline">Procedural medieval islands from 4,100 hex tiles, built with WebGPU and a lot of backtracking.</p>
<p class="subtitle"><a href="https://felixturner.github.io/hex-map-wfc/" target="_blank">Run the live demo</a> · <a href="https://github.com/felixturner/hex-map-wfc" target="_blank">Source code on GitHub</a></p>
</header><figure class="full"><img src="https://felixturner.github.io/hex-map-wfc/article/img/hero.jpg" alt="Hero shot" /><figcaption>Every map is different. Every map is seeded and deterministic.</figcaption></figure><section><p>I've been obsessed with procedural maps since I was a kid rolling dice on the random dungeon tables in the AD&amp;D Dungeon Master's Guide. There was something magical about it — you didn't <em>design</em> the dungeon, you <em>discovered</em> it, one room at a time, and the dice decided whether you got a treasure chamber or a dead end full of rats.</p><p>Years later, I decided to build my own map generator. It creates little medieval island worlds — with roads, rivers, coastlines, cliffs, forests, and villages — entirely procedurally. Built with Three.js WebGPU and TSL shaders, about 4,100 hex cells across 19 grids, generated in ~20 seconds.</p></section><section><h2>Carcassonne, but a Computer Does It</h2><p>The core technique is <strong>Wave Function Collapse</strong> (WFC), an algorithm originally created by <a href="https://github.com/mxgmn/WaveFunctionCollapse">Maxim Gumin</a> that's become a darling of procgen gamedev.</p></section><figure class="small"><img src="https://felixturner.github.io/hex-map-wfc/article/img/carcassonne.jpg" alt="Carcassonne board game" /><figcaption>Hours of fun with map tiles.</figcaption></figure><section><p>If you've ever played <a href="https://www.zmangames.com/game/carcassonne/">Carcassonne</a>, you already understand WFC. You have a stack of tiles and place them so everything lines up. Each tile has edges — grass, road, city. <strong>Adjacent tiles must have matching edges.</strong> A road edge must connect to another road edge. Grass must meet grass. The only difference is that the computer does it faster, and complains less when it gets stuck.</p><p>The twist: hex tiles have 6 edges instead of 4. That's 50% more constraints per tile, and the combinatorial explosion is real. Square WFC is well-trodden territory. Hex WFC is... less so.</p></section><section><h3>Tile Definitions</h3><p>For this map there are 30 different tiles defining grass, water, roads, rivers, coasts and slopes. Each tile in the set has a definition which describes the terrain type of each of its 6 edges, plus a weight used for favoring some tiles over others.</p></section><figure class="inline"><img src="https://felixturner.github.io/hex-map-wfc/article/img/tiles.jpg" alt="Tile set showing road, river, and terrain variants" /><figcaption>30 tile types, each with 6 rotations and 5 elevation levels. That's 900 possible states per cell.</figcaption></figure><section><p>For example this 3-way junction has 3 road edges and 3 grass edges. Tile definition:</p><pre>{ name: 'ROAD_D', mesh: 'hex_road_D',
  edges: { NE: 'road', E: 'grass', SE: 'road', SW: 'grass', W: 'road', NW: 'grass' },
  weight: 2 }</pre></section><figure class="small"><img src="https://felixturner.github.io/hex-map-wfc/article/img/tile-def.jpg" alt="A 3-way road junction tile with its 6 edge types labeled" /><figcaption>Each tile defines 6 edge types. Matching edges is the only rule.</figcaption></figure><section><h3>How WFC Works</h3><ol><li><strong>Start with chaos.</strong> Every cell on the grid begins as a superposition of <em>all possible tiles</em> — all 30 types, all 6 rotations, all 5 elevation levels. Pure possibility.</li>
<li><strong>Collapse the most constrained cell.</strong> Pick the cell with the fewest remaining options (lowest entropy). Randomly choose one of its valid states.</li>
<li><strong>Propagate.</strong> That choice constrains its neighbors. Remove any neighbor states whose edges don't match. This cascades outward — one collapse can eliminate hundreds of possibilities across the grid.</li>
<li><strong>Repeat</strong> until every cell is solved — or you get stuck.</li>
</ol><p>Getting stuck is the interesting part.</p></section><section><h2>The Multi-Grid Problem</h2><p>WFC is reliable for small grids. But as the grid gets bigger, the chance of painting yourself into a dead end goes up fast. A 217-cell hex grid almost never fails. A 4123-cell grid fails regularly.</p><p>The solution: <strong>modular WFC</strong>. Instead of one giant solve, the map is split into 19 hexagonal grids arranged in two rings around a center — about 4,100 cells total. Each grid is solved independently, but it has to match whatever tiles were already placed in neighboring grids. Those border tiles become fixed constraints.</p><p>And sometimes those constraints are simply incompatible. No amount of backtracking inside the current grid can fix a problem that was baked in by a neighbor. This is where I spent a lot of dev time.</p></section><figure class="inline"><img src="https://felixturner.github.io/hex-map-wfc/article/img/grids.jpg" alt="Debug view showing grid boundaries" /><figcaption>5 of 19 grids solved. Each grid is an independent WFC solve, constrained by its neighbors' border tiles.</figcaption></figure><section><h3>Backtracking</h3><p>Here's the dirty secret of WFC: it fails. A lot. You make a series of random choices, propagate constraints, and eventually back yourself into a corner where some cell has zero valid options left. Congratulations, the puzzle is unsolvable.</p><p>The textbook solution is <strong>backtracking</strong> — undo your last decision and try a different tile. My solver tracks every possibility it removes during propagation (a "trail" of deltas), so it can rewind cheaply without copying the entire grid state. It'll try up to 500 backtracks before giving up.</p><p>But backtracking alone isn't enough. The real problem is cross-grid boundaries.</p><h3>The Recovery System</h3><p>After many failed approaches, I landed on a layered recovery system:</p><p><strong>Layer 1: Unfixing.</strong> During the initial constraint propagation, if a neighbor cell creates a contradiction, the solver converts it from a fixed constraint back into a solvable cell. Its <em>own</em> neighbors (two cells out — "anchors") become the new constraints. This is cheap and handles easy cases.</p><p><strong>Layer 2: Local-WFC.</strong> If the main solve fails, the solver runs a mini-WFC on a small radius-2 region around the problem area — re-solving 19 cells in the overlap area to create a more compatible boundary. Up to 5 attempts, each targeting a different problem cell. Local-WFC was the breakthrough. Instead of trying to solve the impossible, go back and change the problem.</p><p><strong>Layer 3: Drop and hide.</strong> Last resort. Drop the offending neighbor cell entirely and place mountain tiles to cover the seams. Mountains are great — their cliff edges match anything, and they look intentional. Nobody questions a mountain.</p></section><figure class="inline"><div class="slideshow slideshow-captioned"><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/before.jpg" alt="Before: neighbor conflict blocks the solve" />Before: neighbor conflict blocks the solve</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/after.jpg" alt="After: Local-WFC patches the boundary" />After: Local-WFC patches the boundary</div></div>
<figcaption>Debug mode showing the carnage. Purple = neighbor conflict. Red = broken tiles.</figcaption></figure><section><h3>The Third Dimension</h3><p>This map isn't flat — it has 5 levels of elevation. Ocean and Grass start at level 0, but slopes and cliffs can move up or down a level. Low slopes go up 1 level, high slopes go up 2 levels. A road tile at level 3 needs to connect to another road tile at level 3, or a slope tile that transitions between levels. Get it wrong and you end up with roads that dead-end into cliff faces or rivers flowing uphill into the sky. The elevation axis turns a 2D constraint problem into a 3D one, and it's where a lot of the tile variety (and a lot of the solver failures) comes from.</p></section><figure class="inline"><div class="slideshow slideshow-captioned"><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/heights.jpg" alt="Natural" />Natural</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/heights-color.jpg" alt="Debug Colors" />Debug Colors</div></div>
<figcaption>Elevation colors.</figcaption></figure><section><p>Tiles are colored with a node-based PBR material - <code>MeshPhysicalNodeMaterial</code> - with a custom TSL color node. Each tile's elevation is encoded in the instance color, which the shader uses to blend between two palette textures — low ground gets summer colors, high ground gets winter.</p></section><section><h2>Hex Coordinates: Surprisingly Weird</h2><p>Hex math is weird. Since there are 6 directions instead of 4, there's no simple mapping between hex positions and 2D x,y coordinates. The naive approach is <strong>offset coordinates</strong> — numbering cells left-to-right, top-to-bottom like a regular grid. This works until you need to find neighbors, compute distances, or do anything involving directions. Then it gets confusing fast, with different formulas for odd and even rows.</p></section><figure class="inline"><img src="https://felixturner.github.io/hex-map-wfc/article/img/coords.jpg" alt="Hexagonal Offset Coords" /><figcaption>Offset coordinates: simple until you need to do anything useful with them.</figcaption></figure><section><p>The better approach: <strong>cube coordinates</strong> (q, r, s where s = -q-r). It's a 3D coordinate system for the three hex axes. Neighbor finding becomes trivial — just add or subtract 1 from two coordinates.</p><p>The good news is that WFC doesn't really care about geometry. It's concerned with which edges match which — it's essentially a graph problem. The hex coordinates only matter for rendering and for the multi-grid layout, where the 19 grids are themselves arranged as a hex-of-hexes with their own offset positions.</p><p>If you've ever worked with hex grids, you owe <a href="https://www.redblobgames.com/grids/hexagons/">Amit Patel at Red Blob Games</a> a debt of gratitude. His hex grid guide is the definitive reference.</p></section><section><h2>Trees, Buildings, and Why Not Everything Should Be WFC</h2><p>Early on, I tried using WFC for tree and building placement. Bad idea. WFC is great at local edge matching but terrible at large-scale patterns. You'd get trees scattered randomly instead of clustered into forests, or buildings spread evenly instead of gathered into villages.</p><p>The solution: good old Perlin noise. A global noise field determines tree density and building placement, completely separate from WFC. Areas where the noise is above a threshold get trees; slightly different noise drives buildings. This gives you organic clustering — forests, clearings, villages — that WFC could never produce. I also used some additional logic to place buildings at the end of roads, ports and windmills on coasts, henges on hilltops etc.</p><p>WFC handles the terrain. Noise handles the decorations. Each tool does what it's good at.</p></section><figure class="inline"><img src="https://felixturner.github.io/hex-map-wfc/article/img/noise.jpg" alt="Village with clustered buildings and surrounding forests" /><figcaption>Buildings cluster along roads. Forests form natural groups. None of this is WFC — it's all noise-based placement.</figcaption></figure><section><h2>Water: Harder Than It Looks</h2><p>Water effects were the hardest visual problem to solve. The ocean isn't just a blue plane — it has animated caustic sparkles and coastal waves that emanate from shorelines.</p></section><figure class="full"><img src="https://felixturner.github.io/hex-map-wfc/article/img/pink-water.jpg" alt="Close-up of ocean debug view" /><figcaption>Pink is the best debug color.</figcaption></figure><section><h3>Sparkles</h3><p>I wanted that 'Zelda: The Wind Waker' cartoon shimmer on the water surface. Originally I tried generating caustics procedurally with four layers of Voronoi noise. This turned out to be very GPU heavy and did not look great. The solution was sampling a small scrolling caustic texture with a simple noise mask, which looks way better and is super cheap. Sometimes the easy solution is the correct solution.</p><h3>Coast Waves</h3><p>Waves are sine bands that radiate outward from coastlines, inspired by <a href="https://www.badnorth.com/">Bad North</a>'s gorgeous shoreline effect. To know "how far from the coast" each pixel is, the system renders a coast mask — a top down orthographic render of the entire map with white for land and black for water — then dilates and blurs it into a gradient. The wave shader reads this gradient to place animated sine bands at regular distance intervals, with noise to break up the pattern.</p></section><figure class="inline"><div class="slideshow slideshow-captioned"><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/water/01-flat.jpg" alt="Flat blue plane" />Flat blue plane</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/water/02-mask.jpg" alt="Water mask" />Water mask</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/water/03-sparkles.jpg" alt="Caustic sparkles" />Caustic sparkles</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/water/04-waves.jpg" alt="Coast waves fat in coves" />Coast waves fat in coves</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/water/05-coves-mask.jpg" alt="Surroundedness mask" />Surroundedness mask</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/water/06-final-waves.jpg" alt="Final water" />Final water</div></div>
<figcaption>Building up the water effect layer by layer.</figcaption></figure><section><h3>The Cove Problem</h3><p>This worked great on straight coastlines. In concave coves and inlets, the wave lines got thick and ugly. The blur-based gradient spreads the same value range over a wider physical area in coves, stretching the wave bands out.</p><p>I tried multiple fixes:</p><ul><li><strong>Screen-space derivatives</strong> to detect gradient stretching — worked at one zoom level, broke at others.</li>
<li><strong>Texture-space gradient magnitude</strong> to detect opposing coast edges canceling out — only detected narrow rivers, not actual problem coves.</li>
<li><strong>Extra dilation passes</strong> — affected straight coasts too.</li>
</ul><p>The fundamental issue: blur encodes "how much land is nearby," not "how far is the nearest coast edge." These are different questions, and no amount of post-processing the blur can extract true distance.</p><p>The solve was to do a CPU-side "surroundedness" probe that checks each water cell's neighbors to detect coves, writing a separate mask texture that thins the waves in enclosed areas. It's kind of a hack but it works and the wave edges thin out nicely at the edges.</p></section><section><h2>Making Tiles in Blender</h2><p>The 3D tile assets come from KayKit's fantastic low-poly <a href="https://kaylousberg.itch.io/kaykit-medieval-hexagon">Medieval Hexagon pack</a>. But it was missing some key connectors needed for a sub-complete tileset, so I dusted off my Blender skills and built new tiles: sloping rivers, river dead-ends, river-to-coast connectors, and several cliff edge variants.</p><p>The key constraint: every tile is exactly 2 world units wide, and edge types must align perfectly at the hex boundaries. Getting UVs right means the texture atlas maps correctly across tile seams. A misaligned UV by even a few pixels creates a visible seam line that breaks the illusion.</p></section><figure class="inline"><img src="https://felixturner.github.io/hex-map-wfc/article/img/3d-tiles.jpg" alt="Blender viewport showing hex tiles" /></figure><section><h2>Making It Pretty</h2><p>The algorithm gets you a valid map. Making it look like a place you'd want to visit is a whole separate problem.</p></section><figure class="full"><img src="https://felixturner.github.io/hex-map-wfc/article/img/pretty.jpg" alt="Completed map beauty shot" /></figure><section><h3>WebGPU and TSL Shaders</h3><p>The renderer is <strong>Three.js with WebGPU</strong> and <strong>TSL</strong> (Three.js Shading Language) — the new node-based shader system that replaces raw GLSL. All the custom visual effects are written in TSL, which reads like a slightly alien dialect of JavaScript that runs on your GPU.</p><h3>The Post-Processing Stack</h3><p>The raw render looks... fine. Flat. Like a board game photographed under fluorescent lights. The post-processing pipeline is what gives it atmosphere:</p><ol><li><strong>GTAO Ambient Occlusion</strong> — darkens crevices between tiles, around buildings and trees. This makes everything feel more solid. The AO result is denoised to reduce speckling. This runs at half resolution since AO and denoising is expensive.</li>
<li><strong>Depth of Field</strong> — tilt-shift blur based on camera distance gives it that miniature/diorama feel. The DOF focal length scales with the camera zoom to give more DOF when zoomed in.</li>
<li><strong>Vignette + Film Grain</strong> — subtle edge darkening and noise. Just enough to feel analog.</li>
</ol></section><figure class="inline"><div class="slideshow slideshow-captioned"><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/postfx/00-normal.jpg" alt="Normals" />Normals</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/postfx/02-ao.jpg" alt="AO" />AO</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/postfx/01-raw.jpg" alt="Raw render" />Raw render</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/postfx/03-with-ao.jpg" alt="AO Composite" />AO Composite</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/postfx/04-with-dof.jpg" alt="DOF" />DOF</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/postfx/05-with-vig-grain.jpg" alt="Vignette and Grain" />Vignette and Grain</div></div>
<figcaption>Post-processing. AO, depth of field and grain do a lot of heavy lifting.</figcaption></figure><section><h3>Dynamic Shadow Maps</h3><p>The shadow map frustum is fitted to the camera view every frame. The visible area is projected into the light's coordinate system to compute the tightest possible bounding box, so no shadow map texels are wasted on off-screen geometry. Zoomed out, shadows cover the whole map at lower resolution. Zoom in, and the shadow map tightens to give you crisp, detailed shadows on individual tiles. This prevents blocky shadow artifacts when you zoom in.</p></section><figure class="inline"><div class="slideshow slideshow-captioned"><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/shadows/01-blurry.jpg" alt="Fixed shadow map" />Fixed shadow map</div><div class="slide"><img src="https://felixturner.github.io/hex-map-wfc/article/img/shadows/02-crisp.jpg" alt="Dynamic shadow map" />Dynamic shadow map</div></div>
<figcaption>Dynamic frustum for crisp detail.</figcaption></figure><section><h2>Optimizations</h2><p>The complete map has thousands of tiles and decorations. Drawing each one individually would kill the frame rate. The solution is two-fold:</p><p><strong>BatchedMesh</strong> — each hex grid gets 2 BatchedMeshes: one for tiles, one for decorations. The beauty of a BatchedMesh is that each mesh can have separate geometry and transforms, but they all render in a single draw call. The GPU handles per-instance transforms and geometry offsets, so CPU cost is essentially zero after setup.</p><p>The whole scene renders in a handful of draw calls regardless of map complexity. That means the base render is cheap, so you can spend your GPU budget on AO, DoF, and color grading instead.</p><p><strong>One Shared Material</strong> — every mesh in the scene shares a single material. The Mesh UVs map into a small palette texture, so they all pull their color from the same image, like a shared paint-by-numbers sheet. One material means zero shader state switches between draw calls, so the GPU can blast through 38 BatchedMeshes without stalling.</p><p>The result: 4,100+ cells, 38 BatchedMeshes, and the whole thing renders at 60fps on desktop and mobile.</p></section><figure class="full"><img src="https://felixturner.github.io/hex-map-wfc/article/img/white.jpg" alt="snow day" /><figcaption>Snow day.</figcaption></figure><section><h2>Summary</h2><p>No dice required this time — but the feeling is the same. You hit a button, the map builds itself, and you discover what the algorithm decided to put there. It's super satisfying to see the road and river systems matching up perfectly. Every time it's different, and every time I find myself exploring for a while. The kid rolling dice on the dungeon tables would be into this.</p></section><section><h2>The Numbers</h2></section><section><h2>Tech Stack</h2><ul class="tech-list"><li><strong>Three.js r183</strong> with WebGPU renderer</li>
<li><strong>TSL</strong> (Three.js Shading Language) for all custom shaders</li>
<li><strong>Web Workers</strong> for off-thread WFC solving</li>
<li><strong>Vite</strong> for builds</li>
<li><strong>BatchedMesh</strong> for efficient tile rendering (one draw call)</li>
<li><strong>Seeded RNG</strong> for deterministic, reproducible maps</li>
</ul></section><section class="cta"><h2>Try It</h2><p><a href="https://felixturner.github.io/hex-map-wfc/" target="_blank">Play with the live demo</a> — click the hex buttons to expand the map, or hit 'Build All' to generate the whole thing. There's a full GUI panel with 50+ tweakable parameters if you want to mess with the lighting, color grading, water effects, and WFC settings.</p><p><a href="https://github.com/felixturner/hex-map-wfc" target="_blank">Full source code on GitHub</a></p></section><footer><h2>Credits and References</h2>
<ul><li><a href="https://kaylousberg.itch.io/kaykit-medieval-hexagon">KayKit Medieval Hexagon Pack</a> — the tile assets that started it all</li>
<li><a href="https://github.com/mxgmn/WaveFunctionCollapse">Maxim Gumin's WFC</a> — the original Wave Function Collapse implementation</li>
<li><a href="https://www.redblobgames.com/grids/hexagons/">Red Blob Games — Hexagonal Grids</a> — the hex grid bible</li>
<li><a href="https://www.boristhebrave.com/2021/10/26/model-synthesis-and-modifying-in-blocks/">Boris the Brave</a> — invaluable WFC articles on modifying in blocks</li>
<li><a href="https://tympanus.net/codrops/2024/10/30/interactive-3d-with-three-js-batchedmesh-and-webgpurenderer/">Codrops</a> — the article that got me started with WebGPU BatchedMesh</li>
<li>Style inspiration: <a href="https://www.badnorth.com/">Bad North</a>, <a href="https://www.dorfromantik.com/">Dorfromantik</a></li>
</ul></footer><section><h2>About Me</h2><p>I'm Felix Turner, a creative developer and founder of <a href="https://airtight.cc">Airtight Interactive</a>. I build interactive visual experiments, WebGL/WebGPU experiences, and generative art.</p><p><a href="https://x.com/felixturner">Twitter</a> · <a href="https://bsky.app/profile/felixturner.bsky.social">Bluesky</a></p></section>]]></description>
      <link>https://felixturner.github.io/hex-map-wfc/article/</link>
      <guid>https://felixturner.github.io/hex-map-wfc/article/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Never the same game twice – Pathetic Fallacy]]></title>
      <description><![CDATA[<p class="has-light-gray-background-color has-background wp-block-paragraph"><a href="https://johnmccoy.org/2026/02/26/we-hear-the-playback-and-it-seems-so-long-ago/">My last essay</a> was a critique of nostalgia, and so to mix things up this post will be a discussion of something from my youth for which I have a great deal of affection, and that is Parker Brothers graphic design from the 1970s. This is admittedly a niche interest, even for me, but I hope you’ll be indulgent. Perhaps you, too, will come to love these beautiful and strange designs.</p>
<p class="wp-block-paragraph">From around 1970 to 1980, the Salem, Massachusetts-based Parker Brothers (now a brand of Hasbro) published games whose innovative and fanciful designs drew inspiration from Pop Art, Op Art, and Madison Avenue advertising. They had boxes, boards, and components that reflected the most current techniques of printing and plastics molding. They were witty, silly, and weird. The other main players in American games at the time were Milton-Bradley, whose art tended towards cartoony, corny, and flat designs, and Ideal, whose games (like <em>Mousetrap</em>) were mostly showcases for their novel plastic components.</p>
<p class="wp-block-paragraph">Parker Brothers design stood out for its style and sophistication, and even as a young nerd I could see that it was special. In fact, I believe they were my introduction, at the age of seven, to the whole concept of graphic design. This isn’t to say that the games were <em>good</em> in the sense of being fun or engaging to play; a lot of them were re-skinned versions of the basic race-around-the-board type that had been popular since the <em>Uncle Wiggly Game</em>. But they looked amazing and they were <em>different</em>.</p>
<p class="wp-block-paragraph">There’s not a lot of sources of information about the company, but there is one very interesting book, <em>The Game Makers : the Story of Parker Brothers from Tiddledy Winks to Trivial Pursuit</em>, which was written by Philip Orbanes in 2004 and published by Harvard Business School Press. From this book I learned that starting with its founding in 1883, Parker Brothers was a family owned operation, and its ethos was decidedly conservative. It produced child-friendly tabletop games that it purchased from independent creators, with little to no research and development and with a small factory that printed simple boards and boxes and made components from simple materials.</p>
<p class="wp-block-paragraph">Along the way they picked up some major properties, like <em>Monopoly</em> and <em>Cluedo</em>, which was rebranded in America as <em>Clue</em>, but they didn’t develop these in-house and they didn’t really have a marketing strategy of any kind. But all that changed in 1968 when the company was sold to General Mills—yes, <em>that</em> General Mills, of Cheerios fame. After the departure of one president who wanted to cash out and retire, and the death of another who died of lung cancer, executive vice president Ranny Barton took the helm, and he immediately replaced the head of manufacturing and the head of sales. Orbanes writes:</p>
<p class="has-light-gray-background-color has-background wp-block-paragraph">In one fell swoop, Ranny Barton had changed Parker Brothers from a family-run, conservative operation to one now seeking high-flying M.B.A;s and marketing wizards in a quest to again double sales. Ranny […] would oversee a group of executives who were experts (165-166).</p>
<p class="wp-block-paragraph">For the first time, the company had project leaders and marketing staff (largely on loan from General Mills). They brought in professionals in design, production, and printing. They bought a new state-of-the art press capable of much finer detail and vibrant colors, and they switched to making their components out of injection molded plastic. They were out to compete, and that meant to advertise on the new medium of television, and to be distinctive.</p>
<p class="wp-block-paragraph">Okay, that’s more than enough backstory. Let’s look at some of the games from this time.</p>
<h3 class="wp-block-heading">Waterworks (1972)</h3>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-block-column is-layout-flow wp-block-column-is-layout-flow c1">
<figure class="wp-block-image size-large"><img data-attachment-id="1457" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/ww1-2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png" data-orig-size="985,1615" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ww1" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=183" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=625" width="625" height="1024" src="https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=625" alt="Waterworks" class="wp-image-1457" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=625 625w, https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=91 91w, https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=183 183w, https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/ww1-1.png 985w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></figure></div>
<p class="wp-block-paragraph">I remember coming across a used copy of this game at a school tag sale when I was in first grade. It looked like nothing else I’d ever seen. The cover art was sparse and focused on its photography. The text was set in Blippo, which seemed shockingly futuristic (it was actually designed in 1969). Most of all, the diegetic title on the manhole cover felt absolutely tangible. I splurged on the 30-cent purchase (my allowance at the time was a quarter).</p>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow c1">
<figure class="wp-block-image size-full"><img data-attachment-id="1433" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/ww3/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png" data-orig-size="803,776" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ww3" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png?w=803" width="803" height="776" src="https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png" alt="Waterworks" class="wp-image-1433" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png 803w, https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png?w=150&amp;h=145 150w, https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png?w=300&amp;h=290 300w, https://johnmccoy.org/wp-content/uploads/2026/02/ww3.png?w=768&amp;h=742 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></figure></div>
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow c1">
<figure class="wp-block-image size-large"><img data-attachment-id="1432" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/ww2-2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png" data-orig-size="1000,654" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ww2" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=840" width="840" height="549" src="https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=840" alt="Waterworks" class="wp-image-1432" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/ww2-1.png 1000w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure></div>
</div>
<p class="wp-block-paragraph">Inside, the cards were wonderful, featuring detailed, photorealistic depictions of pipe fittings, handles, and spouts. They came in a draw/discard bathtub. And there were tiny brass monkey wrenches (perhaps using the existing <em>Clue</em> wrench molds). Everything was designed to be tactile and engaging.</p>
<p class="wp-block-paragraph"><em>Waterworks</em> was designed by Mattiene Moustakas, although whether she designed the gameplay and components, or illustrated the cards, or both, is unclear. She certainly has a <a href="https://www.coroflot.com/mattiene/profile">crazy resume</a>. As for the play, a modern gamer will recognize it as a tile placing game such as <em>Carcassonne</em>; one chained one’s cards together to make a line from handle to spout, while playing pipe junctions and leaks on the opponent’s spread. It was…ok. It was certainly different from the card games I’d played, which were basically War and Solitaire<sup data-fn="6a4a33e4-7a70-4a6c-aaaf-8a5e2c5907f0" class="fn"><a href="#6a4a33e4-7a70-4a6c-aaaf-8a5e2c5907f0" id="6a4a33e4-7a70-4a6c-aaaf-8a5e2c5907f0-link">1</a></sup>.</p>
<h3 class="wp-block-heading">The Inventors (1974)</h3>
<figure class="wp-block-image size-large"><img data-attachment-id="1458" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/in1-3/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png" data-orig-size="1200,603" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="in1" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=840" width="840" height="422" src="https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=840" alt="The Inventors" class="wp-image-1458" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png?w=1024 1024w, https://johnmccoy.org/wp-content/uploads/2026/02/in1-2.png 1200w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><p class="wp-block-paragraph">I’ve mentioned before that the 1970s had a strange retro fad for “old-timey” things, by which I mean Americana from about 1890 to 1905. I am at a loss to explain this. It was a time of serious social problems, from race relations to stagflation. Perhaps there was a longing for a mythical past. The counterculture had drawn heavily on Art Nouveau in poster design, and maybe this trend was breaking into the wider culture. In any case, <em>The Inventors</em> was themed around patenting odd Victorian-looking inventions. The cover art was a highly staged studio shot with models in costumes with props. It featured many of the gadgets referenced in the game, as well as an inventor holding the game itself on his lap, and that kind of self-referentiality was catnip for me. (By the way, the text on the bottom right is in a typeface called Desdemona, which originated in Vienna and has always sounds drama club to me.)</p>
<figure class="wp-block-image size-large"><img data-attachment-id="1438" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/in2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/in2.png" data-orig-size="1000,1000" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="in2" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/in2.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/in2.png?w=840" width="1000" height="1000" src="https://johnmccoy.org/wp-content/uploads/2026/02/in2.png?w=1000" alt="The Inventors" class="wp-image-1438" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/in2.png 1000w, https://johnmccoy.org/wp-content/uploads/2026/02/in2.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/in2.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/in2.png?w=768 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><p class="wp-block-paragraph">The board features a pastiche of Victorian typography and day-glo colors. It features two different tracks to circle the board, but the filigrees and other ornamentation make it seem much more complex. There are handsome cards that feature descriptions of the various inventions to be patented. But the real star of the show is the centerpiece, “the incredible patent picker, move maker machine.”</p>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-block-column is-layout-flow wp-block-column-is-layout-flow c1">
<figure class="wp-block-image size-large"><img data-attachment-id="1440" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/in3/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/in3.png" data-orig-size="545,879" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="in3" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/in3.png?w=186" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/in3.png?w=545" width="545" height="879" src="https://johnmccoy.org/wp-content/uploads/2026/02/in3.png?w=545" alt="The Inventors" class="wp-image-1440" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/in3.png 545w, https://johnmccoy.org/wp-content/uploads/2026/02/in3.png?w=93 93w, https://johnmccoy.org/wp-content/uploads/2026/02/in3.png?w=186 186w" sizes="(max-width: 545px) 85vw, 545px" /></figure></div>
<p class="wp-block-paragraph">This chunky bad boy held the metal clip-on numbers that were the game’s patents, and the “push-pull” dispenser never really worked because the invention cards would bend and fray when you stuck them in. But that didn’t matter, because the real attraction was the dice chute. You placed the dice into the hopper and hit a plunger and they would roll into the tub below, all while ringing a bell.</p>
<p class="wp-block-paragraph"><em>The Inventors</em> was designed by Jeffrey Breslow, who was a student of Marvin Glass, a powerhouse designer that has created <a href="https://en.wikipedia.org/wiki/Marvin_Glass_and_Associates">many of the most recognizable toys of the 20th century</a>. Breslow, working with Glass, also designed <em>Ants in the Pants</em>. As for <em>The Inventors’</em> gameplay: meh. It vaguely resembles <em>Monopoly</em> in that players attempt to succeed financially by developing their properties. But for the most part it’s circling the board in parallel to one’s opponents, with perishingly few actions that directly affect the other players.</p>
<h3 class="wp-block-heading">The Magnificent Race (1975)</h3>
<figure class="wp-block-image size-large"><img data-attachment-id="1459" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/mag1-5/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png" data-orig-size="1000,496" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="mag1" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=840" width="840" height="416" src="https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=840" alt="The Magnificent Race" class="wp-image-1459" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/mag1-4.png 1000w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><p class="wp-block-paragraph">Another old-timey game, <em>The Magnificent Race</em> obviously takes inspiration from Jules Verne’s <em>Around the World in 80 Days</em>. The players must circumnavigate the globe using cars, ships, planes, and balloons. The gimmick of the game is a non-player-character (before there even were NPCs) called Dastardly Dan, represented by a purple marble, who can interfere in, and even win, the titular race.</p>
<p class="wp-block-paragraph">The game’s board shares its typography, color palette, and even curvilinear forms with the Inventors’ board, and I’m pretty sure the same designer did both. One innovation to this board is the paths are not directional, and players may move there arrows in any direction. This may not seem like a particularly distinctive feature today, but it was unusual in 1975.</p>
<figure class="wp-block-image size-large"><img data-attachment-id="1448" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/mag2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png" data-orig-size="1300,1300" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="mag2" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=840" width="840" height="840" src="https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=840" alt="The Magnificent Race" class="wp-image-1448" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png?w=1024 1024w, https://johnmccoy.org/wp-content/uploads/2026/02/mag2.png 1300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><p class="wp-block-paragraph">The components here pull out all the stops. There are big chunky arrows used as player markers, layout cards on which to place “advantages,” a pegboard to track overall progress around the world, and a spinner with colored marbles (including Dastardly Dan) that determines the winner of each of the series of small races that make up the game. Each player drops in a number of marbles based upon their advantages, the device is spun, and the first to drop into a divot near the center wins.</p>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-block-column is-layout-flow wp-block-column-is-layout-flow c2">
<figure class="wp-block-image size-large"><img data-attachment-id="1451" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/mag3-2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png" data-orig-size="1800,959" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="mag3" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=840" width="1024" height="545" src="https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=1024" alt="The Magnificent Race" class="wp-image-1451" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=1024 1024w, https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png?w=1440 1440w, https://johnmccoy.org/wp-content/uploads/2026/02/mag3-1.png 1800w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure></div>
<p class="wp-block-paragraph">When everything is set up it’s pretty impressive. Fun fact: the groovy fake money for the game is printed on green and purple paper that isn’t shelf-stable. I know this because the bills in the copy I purchased for my kids many decades later crumble apart at the slightest touch.</p>
<p class="wp-block-paragraph">The game was designed by Bill Cooke, who co-designed <em>Boggle</em> (also originally published by Parker Brothers). On his <a href="https://www.facebook.com/billcookedesign">Facebook page</a> Cooke has photos including the original schematic drawings for the spinner. But for me the real attraction is the scratchy, cartoony pen drawings, which recall some of the more elaborate designs of Milton Glaser. I would dearly love to know who the illustrator was for these.</p>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-block-column is-layout-flow wp-block-column-is-layout-flow c3">
<figure class="wp-block-image size-large"><img data-attachment-id="1453" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/mag4/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png" data-orig-size="858,706" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="mag4" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=840" width="840" height="691" src="https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=840" alt="The Magnificent Race" class="wp-image-1453" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/mag4.png 858w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure></div>
<p class="wp-block-paragraph">As for the gameplay…this one’s a real let-down. All of the bells and whistles can’t hide that at its core it’s a random chase around the board. However, the spinner <em>is</em> a lot of fun, especially when the Dastardly Dan marble wins.</p>
<h3 class="wp-block-heading">Bonkers (1978)</h3>
<figure class="wp-block-image size-large"><img data-attachment-id="1464" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/bnk1-2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg" data-orig-size="1185,581" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="bnk1" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=840" width="840" height="411" src="https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=840" alt="Bonkers" class="wp-image-1464" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg?w=1024 1024w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk1-1.jpg 1185w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><p class="wp-block-paragraph">Or to refer to it by its full name as printed on the box, <em>This Game is Bonkers</em>. This was not a game my family owned but I played it at friends’ houses and it had <a href="https://youtu.be/Brp3mL1vpJI?si=--Eql8j6kzFSvO3D">an earworm-y television commercial</a> that probably most Americans in their 50s can still sing today.</p>
<figure class="wp-block-image size-large"><img data-attachment-id="1465" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/bnk2/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png" data-orig-size="1200,1200" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="bnk2" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=840" width="840" height="840" src="https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=840" alt="Bonkers" class="wp-image-1465" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=840 840w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png?w=1024 1024w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk2.png 1200w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><p class="wp-block-paragraph">In the Bonkers graphic design Parker Brothers reached an apotheosis. For years they had been cribbing from the cheekier parts of Madison Avenue; here they went full-on Peter Max with shooting stars, lightning bolts, volumetric arrows, and exclamation points everywhere. The board starts pretty empty, but players fill in the spaces with U-shaped cards that change the flow of movement, directing tokens forwards and backwards and eventually into spaces that score or remove points.</p>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-block-column is-layout-flow wp-block-column-is-layout-flow c4">
<figure class="wp-block-image size-large"><img data-attachment-id="1468" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/bnk3/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png" data-orig-size="1536,1200" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="bnk3" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=840" width="1024" height="800" src="https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=1024" alt="Bonkers" class="wp-image-1468" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=1024 1024w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=768 768w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png?w=1440 1440w, https://johnmccoy.org/wp-content/uploads/2026/02/bnk3.png 1536w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure></div>
<p class="wp-block-paragraph">The design couldn’t be more frenetic or bold. Unfortunately, the graphics promise a zanier time than the gameplay delivers. The mechanic of players altering the rules of the game as they go is a good one (see modern games like <em>Fluxx</em>), but that’s not really what’s happening here; instead, the normal clockwise race around the board is being lengthened by digressions. It’s still a fixed track. But man, does it look great.</p>
<p class="wp-block-paragraph"><em>Bonkers</em> was designed by local boy Paul J. Gruen, who lived in West Newbury, just a half-hour drive from Parker Brothers. He also designed <em>Pay Day</em> (1972) for Parker Brothers, another game whose original graphics had pop art origins—in this case with illustrations resembling those of Heinz Edelmann, character designer for the Beatles’ <em>Yellow Submarine</em> (1968).</p>
<figure class="wp-block-image size-large"><img data-attachment-id="1469" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/pay/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg" data-orig-size="992,501" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="pay" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg?w=300" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg?w=840" width="992" height="501" src="https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg?w=992" alt="Pay Day" class="wp-image-1469" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg 992w, https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg?w=150 150w, https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg?w=300 300w, https://johnmccoy.org/wp-content/uploads/2026/02/pay.jpg?w=768 768w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></figure><h3 class="wp-block-heading">That’s enough</h3>
<p class="wp-block-paragraph">I could go on for hours, and it probably feels like I have already. There’s so many wonderful designs from this period: <em>Vertigo</em> (1970), <em>Masterpiece</em> (1970), <em>10-Four Good Buddy</em> (1976), <em>The Mad Magazine Game</em> (1979). Even the original <em>Boggle</em> (1973) cover art is a crazy snapshot of a time of weird innovation: it didn’t actually feature the game<sup data-fn="d7b4ee59-bc18-4ddd-b1bc-a07b8ee46231" class="fn"><a href="#d7b4ee59-bc18-4ddd-b1bc-a07b8ee46231" id="d7b4ee59-bc18-4ddd-b1bc-a07b8ee46231-link">2</a></sup>.</p>
<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex wp-block-column is-layout-flow wp-block-column-is-layout-flow c1">
<figure class="wp-block-image size-large"><img data-attachment-id="1472" data-permalink="https://johnmccoy.org/2026/03/05/never-the-same-game-twice/bog/" data-orig-file="https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg" data-orig-size="525,970" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="bog" data-image-description="" data-image-caption="" data-medium-file="https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg?w=162" data-large-file="https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg?w=525" width="525" height="970" src="https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg?w=525" alt="Boggle" class="wp-image-1472" srcset="https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg 525w, https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg?w=81 81w, https://johnmccoy.org/wp-content/uploads/2026/02/bog.jpg?w=162 162w" sizes="(max-width: 525px) 85vw, 525px" /></figure></div>
<p class="wp-block-paragraph">As the 70s ended, Parker Brothers swung heavily into electronics with toys like <em>Merlin</em> (1978) and their own line of cartridges for the Atari 2600. And in 1985, General Mills merged the company with Kenner, then sold it to Tonka in 1987, before everything eventually got bought up by Hasbro in 1991. But for a brief time in the 70s, Parker Brothers was the one game company that was distinctive, brassy, different. The games themselves were hit-or-miss, but the design always landed.</p>
<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" /><ol class="wp-block-footnotes"><li id="6a4a33e4-7a70-4a6c-aaaf-8a5e2c5907f0">As an aside, I learned the version of Solitaire I knew from my mom, which was a hard-as-nails version that I have never seen anyone else play, so I don’t even know what it would be called. Years later I would learn that most kids played Klondike, which I would scoff at as a baby game. <a href="#6a4a33e4-7a70-4a6c-aaaf-8a5e2c5907f0-link">↩︎</a></li>
<li id="d7b4ee59-bc18-4ddd-b1bc-a07b8ee46231">Also it was set in <a href="https://johnmccoy.org/2017/01/11/know-your-typefaces-optima/">Optima</a>! <a href="#d7b4ee59-bc18-4ddd-b1bc-a07b8ee46231-link">↩︎</a></li>
</ol>
<div class="author-info">
<div class="author-avatar"><img referrerpolicy="no-referrer" alt="Unknown's avatar" src="https://0.gravatar.com/avatar/cadf2a5aeb915389e01109243a9c2747cb78eb8e4537e0c3efa98cbf58bed58c?s=42&amp;d=identicon&amp;r=G" srcset="https://0.gravatar.com/avatar/cadf2a5aeb915389e01109243a9c2747cb78eb8e4537e0c3efa98cbf58bed58c?s=42&amp;d=identicon&amp;r=G 1x, https://0.gravatar.com/avatar/cadf2a5aeb915389e01109243a9c2747cb78eb8e4537e0c3efa98cbf58bed58c?s=63&amp;d=identicon&amp;r=G 1.5x, https://0.gravatar.com/avatar/cadf2a5aeb915389e01109243a9c2747cb78eb8e4537e0c3efa98cbf58bed58c?s=84&amp;d=identicon&amp;r=G 2x, https://0.gravatar.com/avatar/cadf2a5aeb915389e01109243a9c2747cb78eb8e4537e0c3efa98cbf58bed58c?s=126&amp;d=identicon&amp;r=G 3x, https://0.gravatar.com/avatar/cadf2a5aeb915389e01109243a9c2747cb78eb8e4537e0c3efa98cbf58bed58c?s=168&amp;d=identicon&amp;r=G 4x" class="avatar avatar-42" height="42" width="42" /></div>
<div class="author-description">
<h2 class="author-title">Author: John McCoy</h2>
<p class="author-bio">a man, no plan, no canal </p>
</div>
</div>]]></description>
      <link>https://johnmccoy.org/2026/03/05/never-the-same-game-twice/</link>
      <guid>https://johnmccoy.org/2026/03/05/never-the-same-game-twice/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Meta’s AI Smart Glasses and Data Privacy Concerns: Workers Say “We See Everything”]]></title>
      <description><![CDATA[<p>The advertisement is everywhere. The ice hockey player Peter Forsberg is trying on a pair of black glasses. In the viral clip he talks to the glasses, asking who is Sweden’s greatest hockey player of all time.</p><p>They are not just any glasses.</p><p>They are Facebook owner Meta’s new AI glasses.</p><p>The glasses are marketed as an all-in-one assistant that helps the wearer excel at work, capture beautiful sunsets, act as a travel guide and translate foreign languages in real time.</p><p>So powerful that they are meant to compete with smartphones, while the user remains in control of their privacy.</p><p>Reality would prove to be different.</p><p>It is stuffy at the top of the hotel in Nairobi, Kenya. The grey sky presses the heat against the windows. The man in front of us is nervous. If his employer finds out that he is here, he could lose everything.</p><p>He is one of the people few even realise exist – a flesh-and-blood worker in the engine room of the data industry. What he has to say is explosive.</p><p>“In some videos you can see someone going to the toilet, or getting undressed. I don’t think they know, because if they knew they wouldn’t be recording.”</p><p>In Svenska Dagbladet and Göteborgs-Posten’s investigation, the people behind Meta’s smart glasses testify to the hidden stream of privacy-sensitive data that is fed straight into the tech giant’s systems.</p><p>It begins on the other side of the world.</p><p>September 2025 in Menlo Park, the heart of Silicon Valley. Mark Zuckerberg, founder of Meta, the company behind Facebook, Instagram and WhatsApp, is about to present the initiative he hopes will define the company’s future. On gigantic screens, the audience can see him sitting backstage, leaning over a script and rehearsing.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 iaLLOd Body-figure"><div class="FigureMedia-www__sc-1pwc5q9-1 hchdeK FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c7"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/72a18e7a-de56-44ff-93b4-e95b559cbb75?fit=crop&amp;format=auto&amp;h=427&amp;q=90&amp;upscale=true&amp;w=640&amp;s=52f7af4fb64fd65d16a6f3661b0877c3d5a486c7 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/72a18e7a-de56-44ff-93b4-e95b559cbb75?fit=crop&amp;format=auto&amp;h=427&amp;q=90&amp;upscale=true&amp;w=640&amp;s=52f7af4fb64fd65d16a6f3661b0877c3d5a486c7 640w, https://svd.vgc.no/v2/images/72a18e7a-de56-44ff-93b4-e95b559cbb75?fit=crop&amp;format=auto&amp;h=333&amp;q=90&amp;upscale=true&amp;w=500&amp;s=8d134440e623eb92464e64e856aad8b8a7e70905 500w, https://svd.vgc.no/v2/images/72a18e7a-de56-44ff-93b4-e95b559cbb75?fit=crop&amp;format=auto&amp;h=267&amp;q=90&amp;upscale=true&amp;w=400&amp;s=1be58830b6dd6ef17fc4d22409362d2a1961bff6 400w, https://svd.vgc.no/v2/images/72a18e7a-de56-44ff-93b4-e95b559cbb75?fit=crop&amp;format=auto&amp;h=200&amp;q=90&amp;upscale=true&amp;w=300&amp;s=8fe8e4a0f434f8ed2133a6892cfc47cdc5e54b57 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/72a18e7a-de56-44ff-93b4-e95b559cbb75?fit=crop&amp;format=auto&amp;h=427&amp;q=90&amp;upscale=true&amp;w=640&amp;s=52f7af4fb64fd65d16a6f3661b0877c3d5a486c7" alt="Mark Zuckerberg presenting what he hopes to be the future of Meta." data-image-index="1" width="640" height="427" /></picture></noscript></div>
<figcaption class="FigureCaption-www__sc-1pwc5q9-2 fmreYJ">Mark Zuckerberg presenting what he hopes to be the future of Meta. Foto: Nic Coury/AP</figcaption></figure><p>They lie in front of him on the table.</p><p>“Meta Ray-Ban Glasses”.</p><p>He stands up after a while, and puts the glasses on.</p><p>The perspective shifts – on the screens, the audience sees the world through his eyes. Zuckerberg walks through the corridors, towards the stage. On the way, he is met with cheers, fist bumps and a nod from the international music star Diplo.</p><div class="ArticleFactBoxWrapper-www__sc-ksvvks-0 gIdECN"><aside class="StyledArticleFactBox-www__sc-ksvvks-4 bBvQNU is-folded" data-controller="classToggler" data-classtoggler-class-name="is-folded" data-classtoggler-trigger="[data-factbox-toggle]" data-bundle-name="factbox"><div class="ArticleFactBoxContent-www__sc-ksvvks-1 vLZjh"><div class="ArticleFactBoxBody-www__sc-ksvvks-3 cOuIMU"><p><a href="https://www.svd.se/story/dina-ogon-deras-data" target="_blank" rel="noopener noreferrer">Your eyes, their data</a> is an article series about Meta’s new smart glasses. The investigation is a collaboration between Göteborgs-Posten and Svenska Dagbladet and Naipanoi Lepapa, an award-winning investigative freelance journalist based in Nairobi, Kenya.</p><p>In the tech companies’ new digital world, geographical borders have limited significance. Who then has control over the data that is collected? The investigation shows that Meta hires companies around the world to process private images and sensitive information.</p></div></div>
</aside></div><p>On stage, Zuckerberg preaches. He explains that his revolutionary glasses are to be a kind of all-in-one assistant with everything from live translations to facial recognition.</p><p>He concludes by thanking his American team. But what is shown in Menlo Park is just as much the result of a completely different type of work, far away from Silicon Valley.</p><p>The company they work for is called Sama and is a subcontractor to Meta. Here in Kenya’s capital, thousands of people train AI systems, teaching them to recognise and interpret the world.</p><p>They are called data annotators, and they are the manual labourers of the AI revolution. On the screens they draw boxes around flower pots and traffic signs, follow contours, register pixels and name objects: cars, lamps, people. Every image must be described, labelled and quality assured.</p><p>All to make the next generation of smart glasses a little more intelligent – a little more human.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 iaLLOd Body-figure"><div class="FigureMedia-www__sc-1pwc5q9-1 hchdeK FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c8"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/d1738fb9-2f1e-40b8-9af0-04a1205bebd5?fit=crop&amp;format=auto&amp;h=466&amp;q=90&amp;upscale=true&amp;w=640&amp;s=652ff73540041b9230cca98b6946f8bd1950a48c 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/d1738fb9-2f1e-40b8-9af0-04a1205bebd5?fit=crop&amp;format=auto&amp;h=466&amp;q=90&amp;upscale=true&amp;w=640&amp;s=652ff73540041b9230cca98b6946f8bd1950a48c 640w, https://svd.vgc.no/v2/images/d1738fb9-2f1e-40b8-9af0-04a1205bebd5?fit=crop&amp;format=auto&amp;h=364&amp;q=90&amp;upscale=true&amp;w=500&amp;s=b54a4f3698f9544962e2d4494f1bbb02475ed2fd 500w, https://svd.vgc.no/v2/images/d1738fb9-2f1e-40b8-9af0-04a1205bebd5?fit=crop&amp;format=auto&amp;h=291&amp;q=90&amp;upscale=true&amp;w=400&amp;s=3bf3f5cea5508c1e1b0dd571b1b75b0c03640dd0 400w, https://svd.vgc.no/v2/images/d1738fb9-2f1e-40b8-9af0-04a1205bebd5?fit=crop&amp;format=auto&amp;h=218&amp;q=90&amp;upscale=true&amp;w=300&amp;s=1aeed40042f4e138160215c9bac2305cdc49ac27 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/d1738fb9-2f1e-40b8-9af0-04a1205bebd5?fit=crop&amp;format=auto&amp;h=466&amp;q=90&amp;upscale=true&amp;w=640&amp;s=652ff73540041b9230cca98b6946f8bd1950a48c" alt="" data-image-index="2" width="640" height="466" /></picture></noscript></div>
</figure><p>It is an uncomfortable truth for tech giants: the AI revolution is to a large extent built on labor in low-income countries. What we call “machine learning” is often the result of human hands.</p><p>In the multi-million city of Nairobi, <a href="https://www.svd.se/a/ArLXmr">SvD and GP meet Sama workers</a> at an indistinct hotel, at a safe distance from Sama. Some come straight from a night shift, others are preparing for a ten-hour shift in front of the screens.</p><p>The employees have signed extensive confidentiality agreements – if they break them they can lose their jobs – and be thrown back into a life without income, often to the slums. Therefore we publish no names.</p><div class="ArticleFactBoxWrapper-www__sc-ksvvks-0 gIdECN"><aside class="StyledArticleFactBox-www__sc-ksvvks-4 bBvQNU is-folded" data-controller="classToggler" data-classtoggler-class-name="is-folded" data-classtoggler-trigger="[data-factbox-toggle]" data-bundle-name="factbox"><div class="ArticleFactBoxContent-www__sc-ksvvks-1 vLZjh"><div class="ArticleFactBoxBody-www__sc-ksvvks-3 cOuIMU"><p>We have interviewed more than thirty employees at different levels at Meta’s subcontractor Sama in Nairobi.</p><p>Several of them work specifically with annotating videos, images and speech for Meta’s AI systems.</p><p>Others work on other Meta-related projects, such as developing wristband-based gesture controls.</p><p>We have not been granted access to the premises where the data annotation takes place and have not been allowed to see the material that the workers handle.</p><p>We have reviewed employment contracts and other supporting documentation that describe the operations at Sama.</p><p>We have also interviewed former employees at Meta in the US who have worked with the company’s AI services and who confirm that “live data” is annotated in several projects.</p><p>All agreed to be interviewed on condition of anonymity due to fear of reprisals.</p></div></div>
</aside></div><p>The workers in Kenya say that it feels uncomfortable to go to work. They tell us about deeply private video clips, which appear to come straight out of Western homes, from people who use the glasses in their everyday lives.</p><p>Several describe video material showing bathroom visits, sex and other intimate moments.</p><p>Another worker talks about people coming out of bathrooms.</p><p>“Someone may have been walking around with the glasses, or happened to be wearing them, and then the person’s partner was in the bathroom, or they had just come out naked”, an employee says.</p><p><strong>Do you sometimes feel that you are looking straight into other people’s private lives?</strong></p><p>“When you see these videos, it feels that way. But since it is a job, you have to do it. You understand that it is someone’s private life you are looking at, but at the same time you are just expected to carry out the work. You are not supposed to question it. If you start asking questions, you are gone.”</p><p>“We see everything – from living rooms to naked bodies. Meta has that type of content in its databases. People can record themselves in the wrong way and not even know what they are recording. They are real people like you and me”.</p><p>The workers describe videos where people’s bank cards are visible by mistake, and people watching porn while wearing the glasses. Clips that could trigger “enormous scandals” if they were leaked.</p><p>“There are also sex scenes filmed with the smart glasses – someone is wearing them having sex. That is why this is so extremely sensitive. There are cameras everywhere in our office, and you are not allowed to bring your own phones or any device that can record”, an employee says.</p><p>The data annotators also work with transcriptions, where they are to check that the AI assistant in Meta’s glasses has answered users’ questions correctly.</p><p>“It can be about any topics at all. We see chats where someone talks about crimes or protests. It is not just greetings, it can be very dark things as well”, one of the workers says.</p><p>Another recounts a text where a man described a woman he wanted to have sex with:</p><p>“He commented on her body and said that he liked her breasts.”</p><p>2025 becomes a breakthrough for Meta Ray-Ban, which is manufactured in collaboration with the eyewear giant EssilorLuxottica. From having sold two million smart glasses in 2023 and 2024 combined, sales are tripled to seven million units.</p><p>In Sweden, Synsam is one of the major Swedish retailers, as is the chain Synoptik. Some independent opticians also carry the glasses.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 iaLLOd Body-figure"><div class="FigureMedia-www__sc-1pwc5q9-1 hchdeK FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c7"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/66881cad-2e1d-41d0-8251-8e3d97884655?fit=crop&amp;format=auto&amp;h=427&amp;q=90&amp;upscale=true&amp;w=640&amp;s=26fad381d1c9a202e162d4e58f285c90ed749b2e 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/66881cad-2e1d-41d0-8251-8e3d97884655?fit=crop&amp;format=auto&amp;h=427&amp;q=90&amp;upscale=true&amp;w=640&amp;s=26fad381d1c9a202e162d4e58f285c90ed749b2e 640w, https://svd.vgc.no/v2/images/66881cad-2e1d-41d0-8251-8e3d97884655?fit=crop&amp;format=auto&amp;h=333&amp;q=90&amp;upscale=true&amp;w=500&amp;s=325e36c57818d90a4b6d9f2dda374ae93598ccc4 500w, https://svd.vgc.no/v2/images/66881cad-2e1d-41d0-8251-8e3d97884655?fit=crop&amp;format=auto&amp;h=267&amp;q=90&amp;upscale=true&amp;w=400&amp;s=23d198bedefd26ac4061b42a4b92442d36ad4c37 400w, https://svd.vgc.no/v2/images/66881cad-2e1d-41d0-8251-8e3d97884655?fit=crop&amp;format=auto&amp;h=200&amp;q=90&amp;upscale=true&amp;w=300&amp;s=cb20ee15a575fcb4ee5be1209d312843fffb3a7d 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/66881cad-2e1d-41d0-8251-8e3d97884655?fit=crop&amp;format=auto&amp;h=427&amp;q=90&amp;upscale=true&amp;w=640&amp;s=26fad381d1c9a202e162d4e58f285c90ed749b2e" alt="Reporters Ahmed Abdigadir and Julia Lindblom outside Synsam’s flagship store in Gothenburg." data-image-index="3" width="640" height="427" /></picture></noscript></div>
<figcaption class="FigureCaption-www__sc-1pwc5q9-2 fmreYJ">Reporters Ahmed Abdigadir and Julia Lindblom outside Synsam’s flagship store in Gothenburg. Foto: Olof Ohlsson</figcaption></figure><p>Throughout the autumn of 2025, we visit ten retailers in Stockholm and Gothenburg to ask the sales staff how the data from the Meta glasses is processed. Several of the sales people give us reassuring answers. We are told that we ourselves can choose exactly what data is shared with Meta.</p><p>“Nothing is shared with them (Meta). That was a big concern for me as well. Are they going to get access to my data, that is a bit scary, but you have full control”, says an employee at a Synsam store.</p><p>Others are more uncertain.</p><p>“To be completely honest, I don’t know where the data goes, or if they take data at all”, says a shop assistant at an independent optician. Another salesperson points out that the customer can always choose not to share their data:</p><p>“No, it is completely fine – everything stays locally in the app.”</p><p>We buy our own pair of glases at Synsam’s flagship store in Gothenburg.</p><div class="ArticleFactBoxWrapper-www__sc-ksvvks-0 gIdECN"><aside class="StyledArticleFactBox-www__sc-ksvvks-4 bBvQNU is-folded" data-controller="classToggler" data-classtoggler-class-name="is-folded" data-classtoggler-trigger="[data-factbox-toggle]" data-bundle-name="factbox"><div class="ArticleFactBoxContent-www__sc-ksvvks-1 vLZjh"><div class="ArticleFactBoxBody-www__sc-ksvvks-3 cOuIMU"><p>SvD and GP have visited ten eyewear stores in Gothenburg and Stockholm.</p><p>In several cases the staff stated that they did not know:</p><p>What Meta Ray-Ban glasses forward in terms of data.</p><p>Where the information ends up.</p><p>Whether anything is automatically shared with Meta.</p><p>How the user’s voice and video material is processed.</p><p>Several store employees also gave contradictory answers, and many believed that all data stays “locally in the app” – something our tests show is not correct.</p></div></div>
</aside></div><p>At the Göteborgs-Posten newsroom we begin installing them. The glasses are to be connected to an app called Meta AI. Only after several approvals in the app is it possible to get started with the AI function. One of the steps concerns whether we want to share extra data with Meta to help improve their products. We choose “no”.</p><p>The AI functions are activated with the voice command “Hey Meta”. Within ten minutes of the package being opened we begin asking questions. The glasses answer immediately, in English.</p><p>Together with a system developer at Svenska Dagbladet we try to find out whether what the salesperson said is correct, that we can choose not to share our data with Meta. We try to use the glasses without internet connection turned on.</p><p>But that makes it impossible to get help interpreting what we see. The glasses urge us to turn on the connection. When we then analyse the network traffic from the app, we see that the phone has frequent contact with Meta servers in Luleå, Swden, and Denmark.</p><p>In order to answer questions and interpret what the camera sees, the glasses require that data be processed via Meta’s infrastructure – it is not possible to interact with the AI solely locally on the phone.</p><p>What the salespeople say about nothing being shared onwards does not appear to be correct.</p><p>We contact Synsam and Synoptik for an interview about what training the sales staff receive and how it can be that the answers they give are so different. Synsam responded in writing that its role is to inform customers about the applicable terms and to provide internal training, but that responsibility for complying with Swedish law and Meta’s terms ultimately rests with the wearer. Synoptik responded in similar terms, saying its staff are trained in ethics and emphazise the user’s responsibility.</p><p>With the glasses we bought there is also a manual with a QR code that leads to Meta’s privacy policy for wearable products. This in turn links to other pages, such as the Terms of Use for Meta’s AI services.</p><p>At first glance, it appears that we have significant control over our data. It states that voice recordings may only be saved and used for improvement or training of other Meta products if the user actively agrees.</p><p>But for the AI assistant to function, voice, text, image and sometimes video must be processed and may be shared onwards. This data processing is done automatically and cannot be turned off.</p><p>We read further on in the Terms of Use for Meta’s AIs. The terms state that “in some cases, Meta will review your interactions with AIs, including the content of your conversations with or messages to AIs, and this review can be automated or manual (human).”</p><p>It also states that the AIs may store and use information shared with them, and that the user should not share information “that you don’t want the AIs to use and retain, such as information about sensitive topics”.</p><p>The user is given no choice; it is mandatory to participate.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 iaLLOd Body-figure"><div class="FigureMedia-www__sc-1pwc5q9-1 hchdeK FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c10"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/ce82e1c9-9907-4be4-99d9-eceb1f178a0f?fit=crop&amp;format=auto&amp;h=320&amp;q=90&amp;upscale=true&amp;w=640&amp;s=7eed30eff4242434b4fc8e36d22a70e2c61022ef 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/ce82e1c9-9907-4be4-99d9-eceb1f178a0f?fit=crop&amp;format=auto&amp;h=320&amp;q=90&amp;upscale=true&amp;w=640&amp;s=7eed30eff4242434b4fc8e36d22a70e2c61022ef 640w, https://svd.vgc.no/v2/images/ce82e1c9-9907-4be4-99d9-eceb1f178a0f?fit=crop&amp;format=auto&amp;h=250&amp;q=90&amp;upscale=true&amp;w=500&amp;s=1a92f6bbb5b41e591698ce0c4f3dbad201efb6a7 500w, https://svd.vgc.no/v2/images/ce82e1c9-9907-4be4-99d9-eceb1f178a0f?fit=crop&amp;format=auto&amp;h=200&amp;q=90&amp;upscale=true&amp;w=400&amp;s=09e88269a71cd6ef6c1493f8f707b12a4ad1010d 400w, https://svd.vgc.no/v2/images/ce82e1c9-9907-4be4-99d9-eceb1f178a0f?fit=crop&amp;format=auto&amp;h=150&amp;q=90&amp;upscale=true&amp;w=300&amp;s=20e50425a8235acb044f361218078072e2716b19 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/ce82e1c9-9907-4be4-99d9-eceb1f178a0f?fit=crop&amp;format=auto&amp;h=320&amp;q=90&amp;upscale=true&amp;w=640&amp;s=7eed30eff4242434b4fc8e36d22a70e2c61022ef" alt="" data-image-index="4" width="640" height="320" /></picture></noscript></div>
</figure><p>It is not specified how much data may be analysed or for how long it may be stored. Nor is it specified who is given access to the data.</p><p>Data experts we contact in Sweden and abroad question how aware users really are that their data may be used to train Meta’s AI.</p><p>The experts point to an unclear boundary between what is shared voluntarily and what is collected automatically – a boundary that can be difficult to detect.</p><p>When Meta offers services within the EU, the company is subject to the General Data Protection Regulation (GDPR), which requires transparency about how personal data is processed and where that processing takes place.</p><p>Kleanthi Sardeli is a data protection lawyer at None Of Your Business (NOYB), a non-profit organisation in Vienna that has brought several legal cases against Meta. They are currently reviewing the new smart glasses.</p><p>She says there is a clear transparency problem: users may not realise that the camera is recording when they begin speaking to the AI assistant.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 bqxooy Body-figure"><div class="FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c11"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/28762545-2c81-49fa-94ba-e98c9d6dc8b8?fit=crop&amp;format=auto&amp;h=660&amp;q=90&amp;upscale=true&amp;w=640&amp;s=303d49023d996d311252fe6eee7b460ba680bcec 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/28762545-2c81-49fa-94ba-e98c9d6dc8b8?fit=crop&amp;format=auto&amp;h=660&amp;q=90&amp;upscale=true&amp;w=640&amp;s=303d49023d996d311252fe6eee7b460ba680bcec 640w, https://svd.vgc.no/v2/images/28762545-2c81-49fa-94ba-e98c9d6dc8b8?fit=crop&amp;format=auto&amp;h=516&amp;q=90&amp;upscale=true&amp;w=500&amp;s=83408ced954bd52a3a2352c726c7459d81c72444 500w, https://svd.vgc.no/v2/images/28762545-2c81-49fa-94ba-e98c9d6dc8b8?fit=crop&amp;format=auto&amp;h=412&amp;q=90&amp;upscale=true&amp;w=400&amp;s=f8f0157555785065195aca9e557315966c721614 400w, https://svd.vgc.no/v2/images/28762545-2c81-49fa-94ba-e98c9d6dc8b8?fit=crop&amp;format=auto&amp;h=309&amp;q=90&amp;upscale=true&amp;w=300&amp;s=cdbea8656ba20857c7ae97cb649d325328d62eec 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/28762545-2c81-49fa-94ba-e98c9d6dc8b8?fit=crop&amp;format=auto&amp;h=660&amp;q=90&amp;upscale=true&amp;w=640&amp;s=303d49023d996d311252fe6eee7b460ba680bcec" alt="Kleanthi Sardeli." data-image-index="5" width="640" height="660" /></picture></noscript></div>
<figcaption class="FigureCaption-www__sc-1pwc5q9-2 fmreYJ">Kleanthi Sardeli. Foto: Privat</figcaption></figure><p>“If this happens in Europe, both transparency and a legal basis for the processing are lacking,” she says. She believes that explicit consent should be required when data is used to train artificial intelligence.</p><p>“Once the material has been fed into the models, the user in practice loses control over how it is used,” Sardeli says.</p><p>Petter Flink is an IT and security specialist at IMY, the Swedish Authority for Privacy Protection. It is the authority that is to protect Swedes’ personal data and privacy.</p><p>According to him, few people truly consider what they are agreeing to when they start using services such as Meta’s glasses.</p><p>“The user really has no idea what is happening behind the scenes”, says Petter Flink.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 bqxooy Body-figure"><div class="FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c12"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/bea0d967-9fdf-4b5e-ae4f-88cdd11e0f19?fit=crop&amp;format=auto&amp;h=695&amp;q=90&amp;upscale=true&amp;w=640&amp;s=f35cf31f414a4e66ac5a2cf8388abe31427d877f 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/bea0d967-9fdf-4b5e-ae4f-88cdd11e0f19?fit=crop&amp;format=auto&amp;h=695&amp;q=90&amp;upscale=true&amp;w=640&amp;s=f35cf31f414a4e66ac5a2cf8388abe31427d877f 640w, https://svd.vgc.no/v2/images/bea0d967-9fdf-4b5e-ae4f-88cdd11e0f19?fit=crop&amp;format=auto&amp;h=543&amp;q=90&amp;upscale=true&amp;w=500&amp;s=76732d2d065ee6079306139f980a93061c644a97 500w, https://svd.vgc.no/v2/images/bea0d967-9fdf-4b5e-ae4f-88cdd11e0f19?fit=crop&amp;format=auto&amp;h=434&amp;q=90&amp;upscale=true&amp;w=400&amp;s=3d48460ca61ea5968be2359ad6fbd31eea1619ce 400w, https://svd.vgc.no/v2/images/bea0d967-9fdf-4b5e-ae4f-88cdd11e0f19?fit=crop&amp;format=auto&amp;h=326&amp;q=90&amp;upscale=true&amp;w=300&amp;s=954b545908a8d99f456893badf3de6f27e632812 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/bea0d967-9fdf-4b5e-ae4f-88cdd11e0f19?fit=crop&amp;format=auto&amp;h=695&amp;q=90&amp;upscale=true&amp;w=640&amp;s=f35cf31f414a4e66ac5a2cf8388abe31427d877f" alt="Petter Flink." data-image-index="6" width="640" height="695" /></picture></noscript></div>
<figcaption class="FigureCaption-www__sc-1pwc5q9-2 fmreYJ">Petter Flink. Foto: Daniel Larsson</figcaption></figure><p>At the same time, the technology has become both more accessible and more enticing, with new functions that quickly reach a broad audience.</p><p>He emphasises that the data Meta collects is more valuable than the glasses themselves. The more details that can be extracted from the user’s everyday life, the more accurately advertising and services can be targeted at the person.</p><p>"I think few people would want to share the details of their daily lives to that extent. But when it is presented in a fun and appealing way, it becomes harder to see the risks”, says Petter Flink.</p><p>The Swedish Authority for Privacy Protection has not reviewed the Meta glasses.</p><p>“Therefore we cannot comment on where the data ends up”, says Petter Flink.</p><p>According to our sources, sensitive data is not intended to be used to train the AI models.</p><p>Even so, it can still happen.</p><p>“As soon as the device ends up in the hands of users, they do whatever they want with it”, says one of the former Meta employees.</p><p>According to the former Meta employees, faces that appear in annotation data are automatically blurred.</p><p>However, data annotators in Kenya told SvD and GP that the anonymisation does not always work as intended. Faces that are to be covered are sometimes visible. We ask one of the former Meta employees how this is possible.</p><p>“The algorithms sometimes miss. Especially in difficult lighting conditions, certain faces and bodies become visible”.</p><p>Where do the images come from? Can private videos from Sweden end up on screens in Kenya? Those who appear in the images, have they consented to appearing in this way?</p><p>We contact Meta repeatedly for an open interview about how the company informs users about the glasses, what filters are used to prevent private material from reaching annotators, how the chain of subcontractors is audited, and why content showing extremely private situations appears.</p><p>We also ask how long voice recordings and video clips are stored, how the possibility for consumers to object works, in practice, and whether the video clips can come from Swedish users.</p><p>After two months, we receive an email from Meta’s spokesperson in London, Joyce Omope. The letter does not directly answer our questions, but explains how data is transferred from the glasses to the user’s mobile app.</p><p>Instead, Meta refers to its AI terms of use and privacy policy. These do not specify where the data ends up, but they do state that it may be subject to human review.</p><p>We asked Meta to elaborate on how sharing highly private material with subcontractors such as Sama in Kenya can be reconciled with its privacy policy. We posed the same questions to Sama. There was no response.</p><div class="ArticleFactBoxWrapper-www__sc-ksvvks-0 gIdECN"><aside class="StyledArticleFactBox-www__sc-ksvvks-4 bBvQNU is-folded" data-controller="classToggler" data-classtoggler-class-name="is-folded" data-classtoggler-trigger="[data-factbox-toggle]" data-bundle-name="factbox"><div class="ArticleFactBoxContent-www__sc-ksvvks-1 vLZjh"><div class="ArticleFactBoxBody-www__sc-ksvvks-3 cOuIMU"><p>The Meta glasses can take pictures and record video with sound in two ways:</p><p>When pressing a physical button on the glasses.</p><p>When using the voice command “Hey Meta” and asking a question to the AI function.</p><p>The glasses do not record continuously, but are activated only through a button press or voice command.</p><p>Sources: Meta, Synsam.</p></div></div>
</aside></div><p>We receive no additional answers from Meta either and have to make do with what Meta’s spokesperson Joyce Omope first wrote:</p><p>“When live AI is being used, we process that media according to the Meta AI Terms of Service and Privacy Policy.”</p><p>A European Meta executive, who asked not to be named, says it does not matter where the data is processed as long as the data protection rules are equivalent to those in Europe.</p><p>“Many believe that data must be stored within the EU to be protected. But under GDPR it does not matter where the server is located – as long as the country meets the EU’s requirements. If it does not, data may not be sent there”.</p><p>They continue:</p><p>“Technically, we have data centres in Sweden, Denmark and Ireland, but the physical location is actually less relevant. The legal responsibility lies with Meta Ireland, which is the European entity. Where the data is actually processed – in Europe or in the US – does not change the regulatory framework”.</p><p>There is currently no EU decision recognising Kenya as providing an adequate level of protection, but the EU and Kenya began a dialogue on the matter in May 2024. It is expected to take time before an agreement is in place.</p><p>Meta themselves write in their privacy policy that they must transfer, store and process user data globally, since “Meta is a company that operates globally”, and that they share information both internally between offices and data centres and externally with partners, third parties and service providers. Meta explicitly writes that this applies to interactions that people have with AI at Meta, for example content and messages.</p><p>Petra Wierup, a lawyer at the Swedish Authority for Privacy Protection, IMY, says that if Meta is the data controller under GDPR, then they have a responsibility for Swedes’ personal data collected when the glasses are used.</p><figure class="StyledFigure-www__sc-1pwc5q9-3 bqxooy Body-figure"><div class="FlexEmbed-www__sc-1wbqtw2-1 FigureFlexEmbed-www__sc-1pwc5q9-4 kaoCSP fPUnLn StyledLazyWrapper-www__sc-18et8ij-0 jethvf c13"><noscript><picture class="Picture-www__sc-1ny8igm-0 kkeHhm"><source srcset="https://svd.vgc.no/v2/images/67977514-8fac-4641-9c3d-5850d98ef346?fit=crop&amp;format=auto&amp;h=721&amp;q=90&amp;upscale=true&amp;w=640&amp;s=6181c01f377d5d5742deab2ba06d6d4af6c12f2c 640w" sizes="640px" media="(min-width: 640px)" /><source srcset="https://svd.vgc.no/v2/images/67977514-8fac-4641-9c3d-5850d98ef346?fit=crop&amp;format=auto&amp;h=721&amp;q=90&amp;upscale=true&amp;w=640&amp;s=6181c01f377d5d5742deab2ba06d6d4af6c12f2c 640w, https://svd.vgc.no/v2/images/67977514-8fac-4641-9c3d-5850d98ef346?fit=crop&amp;format=auto&amp;h=563&amp;q=90&amp;upscale=true&amp;w=500&amp;s=3ff95a78d2df709b45ed6d823f6b8a2b8833bbd5 500w, https://svd.vgc.no/v2/images/67977514-8fac-4641-9c3d-5850d98ef346?fit=crop&amp;format=auto&amp;h=451&amp;q=90&amp;upscale=true&amp;w=400&amp;s=62ed14c6fa6df996a4bab02de055ccf8046ddeab 400w, https://svd.vgc.no/v2/images/67977514-8fac-4641-9c3d-5850d98ef346?fit=crop&amp;format=auto&amp;h=338&amp;q=90&amp;upscale=true&amp;w=300&amp;s=fb0dde79d75876cda6cb82ac7df2eeea3ef7e66b 300w" sizes="100vw" /><img src="https://svd.vgc.no/v2/images/67977514-8fac-4641-9c3d-5850d98ef346?fit=crop&amp;format=auto&amp;h=721&amp;q=90&amp;upscale=true&amp;w=640&amp;s=6181c01f377d5d5742deab2ba06d6d4af6c12f2c" alt="Petra Wierup." data-image-index="7" width="640" height="721" /></picture></noscript></div>
<figcaption class="FigureCaption-www__sc-1pwc5q9-2 fmreYJ">Petra Wierup. Foto: Pressbild</figcaption></figure><p>“For it to be permitted to use a service provider in a third country (outside the EU), it is required that robust agreements with instructions are in place. It must also be ensured that there is legal support for the transfers, so that the data that is transferred receives continued strong and equivalent protection when it is processed in a third country. The protection must therefore not become weaker when it is processed by subcontractors”, says Petra Wierup.</p><p>At one end, the glasses are marketed as an everyday assistant – a voice in the frame that tells you what you are seeing. At the other end, people in Nairobi sit annotating the most intimate moments the camera captures: open-plan offices, living rooms, bedrooms, bathrooms.</p><p>One annotator sums it up:</p><p>“You think that if they knew about the extent of the data collection, no one would dare to use the glasses”.</p>]]></description>
      <link>https://www.svd.se/a/K8nrV4/metas-ai-smart-glasses-and-data-privacy-concerns-workers-say-we-see-everything</link>
      <guid>https://www.svd.se/a/K8nrV4/metas-ai-smart-glasses-and-data-privacy-concerns-workers-say-we-see-everything</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[GitHub - nikopueringer/CorridorKey: Perfect Green Screen Keys]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">CorridorKey</h1><a id="user-content-corridorkey" class="anchor" aria-label="Permalink: CorridorKey" href="#corridorkey"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<details open="" class="details-reset border rounded-2">
  <summary class="tmp-px-3 py-2">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-camera-video">
    <path d="M16 3.75v8.5a.75.75 0 0 1-1.136.643L11 10.575v.675A1.75 1.75 0 0 1 9.25 13h-7.5A1.75 1.75 0 0 1 0 11.25v-6.5C0 3.784.784 3 1.75 3h7.5c.966 0 1.75.784 1.75 1.75v.675l3.864-2.318A.75.75 0 0 1 16 3.75Zm-6.5 1a.25.25 0 0 0-.25-.25h-7.5a.25.25 0 0 0-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-6.5ZM11 8.825l3.5 2.1v-5.85l-3.5 2.1Z"></path>
</svg>
    <span class="m-1">CorridorKeyMp4.mp4</span>
    <span class="dropdown-caret"></span>
  </summary>

  <video src="https://private-user-images.githubusercontent.com/52174106/555872440-1fb27ea8-bc91-4ebc-818f-5a3b5585af08.mp4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzNjc1MjcsIm5iZiI6MTc3MzM2NzIyNywicGF0aCI6Ii81MjE3NDEwNi81NTU4NzI0NDAtMWZiMjdlYTgtYmM5MS00ZWJjLTgxOGYtNWEzYjU1ODVhZjA4Lm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEzVDAyMDAyN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM4ZjI4NzdmNGQxNjc4MmNlNDJlYTY2ZmQ5NzY5NWI0YWYyMGM4ZWUwMjg3ODI0NWMzMTRkZDE3NzYzNDQyYmEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.VbBTLupkh84apa7Bx2bGA22pH30x459C57gz26XJ0dw" data-canonical-src="https://private-user-images.githubusercontent.com/52174106/555872440-1fb27ea8-bc91-4ebc-818f-5a3b5585af08.mp4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzNjc1MjcsIm5iZiI6MTc3MzM2NzIyNywicGF0aCI6Ii81MjE3NDEwNi81NTU4NzI0NDAtMWZiMjdlYTgtYmM5MS00ZWJjLTgxOGYtNWEzYjU1ODVhZjA4Lm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEzVDAyMDAyN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM4ZjI4NzdmNGQxNjc4MmNlNDJlYTY2ZmQ5NzY5NWI0YWYyMGM4ZWUwMjg3ODI0NWMzMTRkZDE3NzYzNDQyYmEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.VbBTLupkh84apa7Bx2bGA22pH30x459C57gz26XJ0dw" controls="controls" muted="muted" class="d-block rounded-bottom-2 border-top width-fit" style="max-height:640px; min-height: 200px">

  </video>
</details>

<p dir="auto">When you film something against a green screen, the edges of your subject inevitably blend with the green background. This creates pixels that are a mix of your subject's color and the green screen's color. Traditional keyers struggle to untangle these colors, forcing you to spend hours building complex edge mattes or manually rotoscoping. Even modern "AI Roto" solutions typically output a harsh binary mask, completely destroying the delicate, semi-transparent pixels needed for a realistic composite.</p>
<p dir="auto">I built CorridorKey to solve this <em>unmixing</em> problem.</p>
<p dir="auto">You input a raw green screen frame, and the neural network completely separates the foreground object from the green screen. For every single pixel, even the highly transparent ones like motion blur or out-of-focus edges, the model predicts the true, un-multiplied straight color of the foreground element, alongside a clean, linear alpha channel. It doesn't just guess what is opaque and what is transparent; it actively reconstructs the color of the foreground object as if the green screen was never there.</p>
<p dir="auto">No more fighting with garbage mattes or agonizing over "core" vs "edge" keys. Give CorridorKey a hint of what you want, and it separates the light for you.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Alert!</h2><a id="user-content-alert" class="anchor" aria-label="Permalink: Alert!" href="#alert"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This is a brand new release, I'm sure you will discover many ways it can be improved! I invite everyone to help. Join us on the "Corridor Creates" Discord to share ideas, work, forks, etc! <a href="https://discord.gg/zvwUrdWXJm" rel="nofollow">https://discord.gg/zvwUrdWXJm</a></p>
<p dir="auto">Also, if you are a novice at using python scripts much like I was, consider downloading a smart IDE like Antigravity (from google, it's free), downloading this repository, and then asking Antigravity to help you get up and running. I even made a LLM Handover doc in the docs/ directory. This project uses <a href="https://docs.astral.sh/uv/" rel="nofollow">uv</a> to manage dependencies — it handles Python installation, virtual environments, and packages all in one step, so you don't need to worry about any of that.</p>
<p dir="auto">Naturally, I have not tested everything. If you encounter errors, please consider patching the code as needed and submitting a pull request.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Features</h2><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Physically Accurate Unmixing:</strong> Clean extraction of straight color foreground and linear alpha channels, preserving hair, motion blur, and translucency.</li>
<li><strong>Resolution Independent:</strong> The engine dynamically scales inference to handle 4K plates while predicting using its native 2048x2048 high-fidelity backbone.</li>
<li><strong>VFX Standard Outputs:</strong> Natively reads and writes 16-bit and 32-bit Linear float EXR files, preserving true color math for integration in Nuke, Fusion, or Resolve.</li>
<li><strong>Auto-Cleanup:</strong> Includes a morphological cleanup system to automatically prune any tracking markers or tiny background features that slip through CorridorKey's detection.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Hardware Requirements</h2><a id="user-content-hardware-requirements" class="anchor" aria-label="Permalink: Hardware Requirements" href="#hardware-requirements"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This project was designed and built on a Linux workstation (Puget Systems PC) equipped with an NVIDIA RTX Pro 6000 with 96GB of VRAM. The community is ACTIVELY optimizing it for consumer GPUS.</p>
<p dir="auto">The most recent build should work on computers with 6-8 gig of VRAM, and it can run on most Mac systems with unified memory. Yes, it might even work on your old Macbook pro. Let us know on the Discord!</p>
<ul dir="auto">
<li><strong>Windows Users:</strong> To run GPU acceleration natively on Windows, your system MUST have NVIDIA drivers that support <strong>CUDA 12.8 or higher</strong> installed. If your drivers only support older CUDA versions, the installer will likely fallback to the CPU.</li>
<li><strong>GVM (Optional):</strong> Requires approximately <strong>80 GB of VRAM</strong> and utilizes massive Stable Video Diffusion models.</li>
<li><strong>VideoMaMa (Optional):</strong> Natively requires a massive chunk of VRAM as well (originally 80GB+). While the community has tweaked the architecture to run at less than 24GB, those extreme memory optimizations have not yet been fully implemented in this repository.</li>
</ul>
<p dir="auto">Because GVM and VideoMaMa have huge model file sizes and extreme hardware requirements, installing their modules is completely optional. You can always provide your own Alpha Hints generated from other, lighter software.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Getting Started</h2><a id="user-content-getting-started" class="anchor" aria-label="Permalink: Getting Started" href="#getting-started"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">1. Installation</h3><a id="user-content-1-installation" class="anchor" aria-label="Permalink: 1. Installation" href="#1-installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This project uses <strong><a href="https://docs.astral.sh/uv/" rel="nofollow">uv</a></strong> to manage Python and all dependencies. uv is a fast, modern replacement for pip that automatically handles Python versions, virtual environments, and package installation in a single step. You do <strong>not</strong> need to install Python yourself — uv does it for you.</p>
<p dir="auto"><strong>For Windows Users (Automated):</strong></p>
<ol dir="auto">
<li>Clone or download this repository to your local machine.</li>
<li>Double-click <code>Install_CorridorKey_Windows.bat</code>. This will automatically install uv (if needed), set up your Python environment, install all dependencies, and download the CorridorKey model.
<blockquote>
<p dir="auto"><strong>Note:</strong> If this is the first time installing uv, any terminal windows you already had open won't see it. The installer script handles the current window automatically, but if you open a new terminal and get "'uv' is not recognized", just close and reopen that terminal.</p>
</blockquote>
</li>
<li>(Optional) Double-click <code>Install_GVM_Windows.bat</code> and <code>Install_VideoMaMa_Windows.bat</code> to download the heavy optional Alpha Hint generator weights.</li>
</ol>
<p dir="auto"><strong>For Linux / Mac Users:</strong></p>
<ol dir="auto">
<li>Clone or download this repository to your local machine.</li>
<li>Install uv if you don't have it:
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="curl -LsSf https://astral.sh/uv/install.sh | sh"><pre>curl -LsSf https://astral.sh/uv/install.sh <span class="pl-k">|</span> sh</pre></div>
</li>
<li>Install all dependencies (uv will download Python 3.10+ automatically if needed):
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="uv sync"><pre>uv sync</pre></div>
</li>
<li><strong>Download the Models:</strong> You must manually download these open-source foundational models and place them in their exact respective folders:
<ul dir="auto">
<li><strong>CorridorKey v1.0 Model (~300MB):</strong> <a href="https://huggingface.co/nikopueringer/CorridorKey_v1.0/resolve/main/CorridorKey_v1.0.pth" rel="nofollow">Download CorridorKey_v1.0.pth</a>
<ul dir="auto">
<li>Place inside: <code>CorridorKeyModule/checkpoints/</code> and ensure it is named exactly <code>CorridorKey.pth</code>.</li>
</ul>
</li>
<li><strong>GVM Weights (Optional):</strong> <a href="https://huggingface.co/geyongtao/gvm" rel="nofollow">HuggingFace: geyongtao/gvm</a>
<ul dir="auto">
<li>Download using the CLI: <code>uv run hf download geyongtao/gvm --local-dir gvm_core/weights</code></li>
</ul>
</li>
<li><strong>VideoMaMa Weights (Optional):</strong> <a href="https://huggingface.co/SammyLim/VideoMaMa" rel="nofollow">HuggingFace: SammyLim/VideoMaMa</a>
<ul dir="auto">
<li>Download the VideoMaMa fine-tuned weights:
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="uv run hf download SammyLim/VideoMaMa --local-dir VideoMaMaInferenceModule/checkpoints/VideoMaMa"><pre class="notranslate"><code>uv run hf download SammyLim/VideoMaMa --local-dir VideoMaMaInferenceModule/checkpoints/VideoMaMa
</code></pre></div>
</li>
<li>VideoMaMa also requires the Stable Video Diffusion base model (VAE + image encoder only, ~2.5GB). Accept the license at <a href="https://huggingface.co/stabilityai/stable-video-diffusion-img2vid-xt" rel="nofollow">stabilityai/stable-video-diffusion-img2vid-xt</a>, then:
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="uv run hf download stabilityai/stable-video-diffusion-img2vid-xt \
  --local-dir VideoMaMaInferenceModule/checkpoints/stable-video-diffusion-img2vid-xt \
  --include &quot;feature_extractor/*&quot; &quot;image_encoder/*&quot; &quot;vae/*&quot; &quot;model_index.json&quot;"><pre class="notranslate"><code>uv run hf download stabilityai/stable-video-diffusion-img2vid-xt \
  --local-dir VideoMaMaInferenceModule/checkpoints/stable-video-diffusion-img2vid-xt \
  --include "feature_extractor/*" "image_encoder/*" "vae/*" "model_index.json"
</code></pre></div>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">2. How it Works</h3><a id="user-content-2-how-it-works" class="anchor" aria-label="Permalink: 2. How it Works" href="#2-how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">CorridorKey requires two inputs to process a frame:</p>
<ol dir="auto">
<li><strong>The Original RGB Image:</strong> The to-be-processed green screen footage. This requires the sRGB color gamut (interchangeable with REC709 gamut), and the engine can ingest either an sRGB gamma or Linear gamma curve.</li>
<li><strong>A Coarse Alpha Hint:</strong> A rough black-and-white mask that generally isolates the subject. This does <em>not</em> need to be precise. It can be generated by you with a rough chroma key or AI roto.</li>
</ol>
<p dir="auto">I've had the best results using GVM or VideoMaMa to create the AlphaHint, so I've repackaged those projects and integrated them here as optional modules inside <code>clip_manager.py</code>. Here is how they compare:</p>
<ul dir="auto">
<li><strong>GVM:</strong> Completely automatic and requires no additional input. It works exceptionally well for people, but can struggle with inanimate objects.</li>
<li><strong>VideoMaMa:</strong> Requires you to provide a rough VideoMamaMaskHint (often drawn by hand or AI) telling it what you want to key. If you choose to use this, place your mask hint in the <code>VideoMamaMaskHint/</code> folder that the wizard creates for your shot. VideoMaMa results are spectacular and can be controlled more easily than GVM due to this mask hint.</li>
</ul>
<p dir="auto">Perhaps in the future, I will implement other generators for the AlphaHint! In the meantime, the better your Alpha Hint, the better CorridorKey's final result will be. Experiment with different amounts of mask erosion or feathering. The model was trained on coarse, blurry, eroded masks, and is exceptional at filling in details from the hint. However, it is generally less effective at subtracting unwanted mask details if your Alpha Hint is expanded too far.</p>
<p dir="auto">Please give feedback and share your results!</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Docker (Linux + NVIDIA GPU)</h3><a id="user-content-docker-linux--nvidia-gpu" class="anchor" aria-label="Permalink: Docker (Linux + NVIDIA GPU)" href="#docker-linux--nvidia-gpu"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you prefer not to install dependencies locally, you can run CorridorKey in Docker.</p>
<p dir="auto">Prerequisites:</p>
<ul dir="auto">
<li>Docker Engine + Docker Compose plugin installed.</li>
<li>NVIDIA driver installed on the host (Linux), with CUDA compatibility for the PyTorch CUDA 12.6 wheels used by this project.</li>
<li>NVIDIA Container Toolkit installed and configured for Docker (<code>nvidia-smi</code> should work on host, and <code>docker run --rm --gpus all nvidia/cuda:12.6.3-runtime-ubuntu22.04 nvidia-smi</code> should succeed).</li>
</ul>
<ol dir="auto">
<li>Build the image:
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="docker build -t corridorkey:latest ."><pre>docker build -t corridorkey:latest <span class="pl-c1">.</span></pre></div>
</li>
<li>Run an action directly (example: inference):
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="docker run --rm -it --gpus all \
  -e OPENCV_IO_ENABLE_OPENEXR=1 \
  -v &quot;$(pwd)/ClipsForInference:/app/ClipsForInference&quot; \
  -v &quot;$(pwd)/Output:/app/Output&quot; \
  -v &quot;$(pwd)/CorridorKeyModule/checkpoints:/app/CorridorKeyModule/checkpoints&quot; \
  -v &quot;$(pwd)/gvm_core/weights:/app/gvm_core/weights&quot; \
  -v &quot;$(pwd)/VideoMaMaInferenceModule/checkpoints:/app/VideoMaMaInferenceModule/checkpoints&quot; \
  corridorkey:latest --action run_inference --device cuda"><pre>docker run --rm -it --gpus all \
  -e OPENCV_IO_ENABLE_OPENEXR=1 \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/ClipsForInference:/app/ClipsForInference<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/Output:/app/Output<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/CorridorKeyModule/checkpoints:/app/CorridorKeyModule/checkpoints<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/gvm_core/weights:/app/gvm_core/weights<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/VideoMaMaInferenceModule/checkpoints:/app/VideoMaMaInferenceModule/checkpoints<span class="pl-pds">"</span></span> \
  corridorkey:latest --action run_inference --device cuda</pre></div>
</li>
<li>Docker Compose (recommended for repeat runs):
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="docker compose build
docker compose --profile gpu run --rm corridorkey --action run_inference --device cuda
docker compose --profile gpu run --rm corridorkey --action list
docker compose --profile cpu run --rm corridorkey-cpu --action run_inference --device cpu"><pre>docker compose build
docker compose --profile gpu run --rm corridorkey --action run_inference --device cuda
docker compose --profile gpu run --rm corridorkey --action list
docker compose --profile cpu run --rm corridorkey-cpu --action run_inference --device cpu</pre></div>
</li>
<li>Optional: pin to specific GPU(s) for multi-GPU workstations:
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="NVIDIA_VISIBLE_DEVICES=0 docker compose --profile gpu run --rm corridorkey --action list
NVIDIA_VISIBLE_DEVICES=1,2 docker compose --profile gpu run --rm corridorkey --action run_inference --device cuda"><pre>NVIDIA_VISIBLE_DEVICES=0 docker compose --profile gpu run --rm corridorkey --action list
NVIDIA_VISIBLE_DEVICES=1,2 docker compose --profile gpu run --rm corridorkey --action run_inference --device cuda</pre></div>
</li>
</ol>
<p dir="auto">Notes:</p>
<ul dir="auto">
<li>You still need to place model weights in the same folders used by native runs (mounted above).</li>
<li>The container does not include kernel GPU drivers; those always come from the host. The image provides user-space dependencies and relies on Docker's NVIDIA runtime to pass through driver libraries/devices.</li>
<li>The wizard works too, but use a path inside the container, for example:
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="docker run --rm -it --gpus all \
  -e OPENCV_IO_ENABLE_OPENEXR=1 \
  -v &quot;$(pwd)/ClipsForInference:/app/ClipsForInference&quot; \
  -v &quot;$(pwd)/Output:/app/Output&quot; \
  -v &quot;$(pwd)/CorridorKeyModule/checkpoints:/app/CorridorKeyModule/checkpoints&quot; \
  -v &quot;$(pwd)/gvm_core/weights:/app/gvm_core/weights&quot; \
  -v &quot;$(pwd)/VideoMaMaInferenceModule/checkpoints:/app/VideoMaMaInferenceModule/checkpoints&quot; \
  corridorkey:latest --action wizard --win_path /app/ClipsForInference
docker compose --profile gpu run --rm corridorkey --action wizard --win_path /app/ClipsForInference"><pre>docker run --rm -it --gpus all \
  -e OPENCV_IO_ENABLE_OPENEXR=1 \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/ClipsForInference:/app/ClipsForInference<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/Output:/app/Output<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/CorridorKeyModule/checkpoints:/app/CorridorKeyModule/checkpoints<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/gvm_core/weights:/app/gvm_core/weights<span class="pl-pds">"</span></span> \
  -v <span class="pl-s"><span class="pl-pds">"</span><span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/VideoMaMaInferenceModule/checkpoints:/app/VideoMaMaInferenceModule/checkpoints<span class="pl-pds">"</span></span> \
  corridorkey:latest --action wizard --win_path /app/ClipsForInference
docker compose --profile gpu run --rm corridorkey --action wizard --win_path /app/ClipsForInference</pre></div>
</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">3. Usage: The Command Line Wizard</h3><a id="user-content-3-usage-the-command-line-wizard" class="anchor" aria-label="Permalink: 3. Usage: The Command Line Wizard" href="#3-usage-the-command-line-wizard"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">For the easiest experience, use the provided launcher scripts. These scripts launch a prompt-based configuration wizard in your terminal.</p>
<ul dir="auto">
<li><strong>Windows:</strong> Drag-and-drop a video file or folder onto <code>CorridorKey_DRAG_CLIPS_HERE_local.bat</code> (Note: Only launch via Drag-and-Drop or CMD. Double-clicking the <code>.bat</code> directly will throw an error).</li>
<li><strong>Linux / Mac:</strong> Run or drag-and-drop a video file or folder onto <code>./CorridorKey_DRAG_CLIPS_HERE_local.sh</code></li>
</ul>
<p dir="auto"><strong>Workflow Steps:</strong></p>
<ol dir="auto">
<li><strong>Launch:</strong> You can drag-and-drop a single loose video file (like an <code>.mp4</code>), a shot folder containing image sequences, or even a master "batch" folder containing multiple different shots all at once onto the launcher script.</li>
<li><strong>Organization:</strong> The wizard will detect what you dragged in. If you dropped loose video files or unorganized folders, the first prompt will ask if you want it to organize your clips into the proper structure.
<ul dir="auto">
<li>If you say Yes, the script will automatically create a shot folder, move your footage into an <code>Input/</code> sub-folder, and generate empty <code>AlphaHint/</code> and <code>VideoMamaMaskHint/</code> folders for you. This structure is required for the engine to pair your hints and footage correctly!</li>
</ul>
</li>
<li><strong>Generate Hints (Optional):</strong> If the wizard detects your shots are missing an <code>AlphaHint</code>, it will ask if you want to generate them automatically using the repackaged GVM or VideoMaMa modules.</li>
<li><strong>Configure:</strong> Once your clips have both Inputs and AlphaHints, select "Process Ready Clips". The wizard will prompt you to configure the run:
<ul dir="auto">
<li><strong>Gamma Space:</strong> Tell the engine if your sequence uses a Linear or sRGB gamma curve.</li>
<li><strong>Despill Strength:</strong> This is a traditional despill filter (0-10), if you wish to have it baked into the output now as opposed to applying it in your comp later.</li>
<li><strong>Auto-Despeckle:</strong> Toggle automatic cleanup and define the size threshold. This isn't just for tracking dots, it removes any small, disconnected islands of pixels.</li>
<li><strong>Refiner Strength:</strong> Use the default (1.0) unless you are experimenting with extreme detail pushing.</li>
</ul>
</li>
<li><strong>Result:</strong> The engine will generate several folders inside your shot directory:
<ul dir="auto">
<li><code>/Matte</code>: The raw Linear Alpha channel (EXR).</li>
<li><code>/FG</code>: The raw Straight Foreground Color Object. (Note: The engine natively computes this in the sRGB gamut. You must manually convert this pass to linear gamma before being combined with the alpha in your compositing program).</li>
<li><code>/Processed</code>: An RGBA image containing the Linear Foreground premultiplied against the Linear Alpha (EXR). This pass exists so you can immediately drop the footage into Premiere/Resolve for a quick preview without dealing with complex premultiplication routing. However, if you want more control over your image, working with the raw FG and Matte outputs will give you that.</li>
<li><code>/Comp</code>: A simple preview of the key composited over a checkerboard (PNG).</li>
</ul>
</li>
</ol>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">But What About Training and Datasets?</h2><a id="user-content-but-what-about-training-and-datasets" class="anchor" aria-label="Permalink: But What About Training and Datasets?" href="#but-what-about-training-and-datasets"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If enough people find this project interesting I'll get the training program and datasets uploaded so we can all really go to town making the absolute best keyer fine tunes! Just hit me with some messages on the Corridor Creates discord or here. If enough people lock in, I'll get this stuff packaged up. Hardware requirements are beefy and the gigabytes are plentiful so I don't want to commit the time unless there's demand.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Device Selection</h2><a id="user-content-device-selection" class="anchor" aria-label="Permalink: Device Selection" href="#device-selection"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">By default, CorridorKey auto-detects the best available compute device: <strong>CUDA &gt; MPS &gt; CPU</strong>.</p>
<p dir="auto"><strong>Override via CLI flag:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="uv run python clip_manager.py --action wizard --win_path &quot;V:\...&quot; --device mps
uv run python clip_manager.py --action run_inference --device cpu"><pre>uv run python clip_manager.py --action wizard --win_path <span class="pl-s"><span class="pl-pds">"</span>V:\...<span class="pl-pds">"</span></span> --device mps
uv run python clip_manager.py --action run_inference --device cpu</pre></div>
<p dir="auto"><strong>Override via environment variable:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export CORRIDORKEY_DEVICE=cpu
uv run python clip_manager.py --action wizard --win_path &quot;V:\...&quot;"><pre><span class="pl-k">export</span> CORRIDORKEY_DEVICE=cpu
uv run python clip_manager.py --action wizard --win_path <span class="pl-s"><span class="pl-pds">"</span>V:\...<span class="pl-pds">"</span></span></pre></div>
<p dir="auto">Priority: <code>--device</code> flag &gt; <code>CORRIDORKEY_DEVICE</code> env var &gt; auto-detect.</p>
<p dir="auto"><strong>Mac users (Apple Silicon):</strong> MPS support is experimental in PyTorch. If you encounter operator errors, set <code>PYTORCH_ENABLE_MPS_FALLBACK=1</code> to fall back to CPU for unsupported ops:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export PYTORCH_ENABLE_MPS_FALLBACK=1"><pre><span class="pl-k">export</span> PYTORCH_ENABLE_MPS_FALLBACK=1</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Backend Selection</h2><a id="user-content-backend-selection" class="anchor" aria-label="Permalink: Backend Selection" href="#backend-selection"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">CorridorKey supports two inference backends:</p>
<ul dir="auto">
<li><strong>Torch</strong> (default on Linux/Windows) — CUDA, MPS, or CPU</li>
<li><strong>MLX</strong> (Apple Silicon) — native Metal acceleration, no Torch overhead</li>
</ul>
<p dir="auto">Resolution: <code>--backend</code> flag &gt; <code>CORRIDORKEY_BACKEND</code> env var &gt; auto-detect.
Auto mode prefers MLX on Apple Silicon when available.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">MLX Setup (Apple Silicon)</h3><a id="user-content-mlx-setup-apple-silicon" class="anchor" aria-label="Permalink: MLX Setup (Apple Silicon)" href="#mlx-setup-apple-silicon"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>
<p dir="auto">Install the MLX backend:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="uv pip install corridorkey-mlx@git+https://github.com/nikopueringer/corridorkey-mlx.git"><pre>uv pip install corridorkey-mlx@git+https://github.com/nikopueringer/corridorkey-mlx.git</pre></div>
</li>
<li>
<p dir="auto">Obtain the MLX weights (<code>.safetensors</code>) — pick <strong>one</strong> option:</p>
<p dir="auto"><strong>Option A — Download pre-converted weights (simplest):</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Download weights from GitHub Releases into a local cache directory
uv run python -m corridorkey_mlx weights download

# Print the cached path, then copy to the checkpoints folder
WEIGHTS=$(uv run python -m corridorkey_mlx weights download --print-path)
cp &quot;$WEIGHTS&quot; CorridorKeyModule/checkpoints/corridorkey_mlx.safetensors"><pre><span class="pl-c"><span class="pl-c">#</span> Download weights from GitHub Releases into a local cache directory</span>
uv run python -m corridorkey_mlx weights download

<span class="pl-c"><span class="pl-c">#</span> Print the cached path, then copy to the checkpoints folder</span>
WEIGHTS=<span class="pl-s"><span class="pl-pds">$(</span>uv run python -m corridorkey_mlx weights download --print-path<span class="pl-pds">)</span></span>
cp <span class="pl-s"><span class="pl-pds">"</span><span class="pl-smi">$WEIGHTS</span><span class="pl-pds">"</span></span> CorridorKeyModule/checkpoints/corridorkey_mlx.safetensors</pre></div>
<p dir="auto"><strong>Option B — Convert from an existing <code>.pth</code> checkpoint:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Clone the MLX repo (contains the conversion script)
git clone https://github.com/nikopueringer/corridorkey-mlx.git
cd corridorkey-mlx
uv sync

# Convert (point --checkpoint at your CorridorKey.pth)
uv run python scripts/convert_weights.py \
    --checkpoint ../CorridorKeyModule/checkpoints/CorridorKey_v1.0.pth \
    --output ../CorridorKeyModule/checkpoints/corridorkey_mlx.safetensors
cd .."><pre><span class="pl-c"><span class="pl-c">#</span> Clone the MLX repo (contains the conversion script)</span>
git clone https://github.com/nikopueringer/corridorkey-mlx.git
<span class="pl-c1">cd</span> corridorkey-mlx
uv sync

<span class="pl-c"><span class="pl-c">#</span> Convert (point --checkpoint at your CorridorKey.pth)</span>
uv run python scripts/convert_weights.py \
    --checkpoint ../CorridorKeyModule/checkpoints/CorridorKey_v1.0.pth \
    --output ../CorridorKeyModule/checkpoints/corridorkey_mlx.safetensors
<span class="pl-c1">cd</span> ..</pre></div>
<p dir="auto">Either way the final file must be at:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CorridorKeyModule/checkpoints/corridorkey_mlx.safetensors"><pre class="notranslate"><code>CorridorKeyModule/checkpoints/corridorkey_mlx.safetensors
</code></pre></div>
</li>
<li>
<p dir="auto">Run with auto-detection or explicit backend:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="CORRIDORKEY_BACKEND=mlx uv run python clip_manager.py --action run_inference"><pre>CORRIDORKEY_BACKEND=mlx uv run python clip_manager.py --action run_inference</pre></div>
</li>
</ol>
<p dir="auto">MLX uses img_size=2048 by default (same as Torch).</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Troubleshooting</h3><a id="user-content-troubleshooting" class="anchor" aria-label="Permalink: Troubleshooting" href="#troubleshooting"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>"No .safetensors checkpoint found"</strong> — place MLX weights in <code>CorridorKeyModule/checkpoints/</code></li>
<li><strong>"corridorkey_mlx not installed"</strong> — run <code>uv pip install corridorkey-mlx@git+https://github.com/nikopueringer/corridorkey-mlx.git</code></li>
<li><strong>"MLX requires Apple Silicon"</strong> — MLX only works on M1+ Macs</li>
<li><strong>Auto picked Torch unexpectedly</strong> — set <code>CORRIDORKEY_BACKEND=mlx</code> explicitly</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Advanced Usage</h2><a id="user-content-advanced-usage" class="anchor" aria-label="Permalink: Advanced Usage" href="#advanced-usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">For developers looking for more details on the specifics of what is happening in the CorridorKey engine, check out the README in the <code>/CorridorKeyModule</code> folder. We also have a dedicated handover document outlining the pipeline architecture for AI assistants in <code>/docs/LLM_HANDOVER.md</code>.</p>
<p dir="auto">You can also explore the full, auto-generated codebase documentation on <a href="https://deepwiki.com/nikopueringer/CorridorKey" rel="nofollow">DeepWiki</a>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Running Tests</h3><a id="user-content-running-tests" class="anchor" aria-label="Permalink: Running Tests" href="#running-tests"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The project includes unit tests for the color math and compositing pipeline. No GPU or model weights required — tests run in a few seconds on any machine.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="uv sync --group dev   # install test dependencies (pytest)
uv run pytest          # run all tests
uv run pytest -v       # verbose output (shows each test name)"><pre>uv sync --group dev   <span class="pl-c"><span class="pl-c">#</span> install test dependencies (pytest)</span>
uv run pytest          <span class="pl-c"><span class="pl-c">#</span> run all tests</span>
uv run pytest -v       <span class="pl-c"><span class="pl-c">#</span> verbose output (shows each test name)</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">CorridorKey Licensing and Permissions</h2><a id="user-content-corridorkey-licensing-and-permissions" class="anchor" aria-label="Permalink: CorridorKey Licensing and Permissions" href="#corridorkey-licensing-and-permissions"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use this tool for whatever you'd like, including for processing images as part of a commercial project! You MAY NOT repackage this tool and sell it, and any variations or improvements of this tool that are released must remain under the same license, and must include the name Corridor Key.</p>
<p dir="auto">You MAY NOT offer inference with this model as a paid API service. If you run a commercial software package or inference service and wish to incoporate this tool into your software, shoot us an email to work out an agreement! I promise we're easy to work with. <a href="mailto:contact@corridordigital.com">contact@corridordigital.com</a>. Outside of the stipulations listed above, this license is effectively a variation of <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="nofollow">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0)</a></p>
<p dir="auto">Please keep the Corridor Key name in any future forks or releases!</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Acknowledgements and Licensing</h2><a id="user-content-acknowledgements-and-licensing" class="anchor" aria-label="Permalink: Acknowledgements and Licensing" href="#acknowledgements-and-licensing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">CorridorKey integrates several open-source modules for Alpha Hint generation. We would like to explicitly credit and thank the following research teams:</p>
<ul dir="auto">
<li><strong>Generative Video Matting (GVM):</strong> Developed by the Advanced Intelligent Machines (AIM) research team at Zhejiang University. The GVM code and models are heavily utilized in the <code>gvm_core</code> module. Their work is licensed under the <a href="https://opensource.org/license/bsd-2-clause" rel="nofollow">2-clause BSD License (BSD-2-Clause)</a>. You can find their source repository here: <a href="https://github.com/aim-uofa/GVM">aim-uofa/GVM</a>.</li>
<li><strong>VideoMaMa:</strong> Developed by the CVLAB at KAIST. The VideoMaMa architecture is utilized within the <code>VideoMaMaInferenceModule</code>. Their code is released under the <a href="https://creativecommons.org/licenses/by-nc/4.0/" rel="nofollow">Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0)</a>, and their specific foundation model checkpoints (<code>dino_projection_mlp.pth</code>, <code>unet/*</code>) are subject to the <a href="https://stability.ai/license" rel="nofollow">Stability AI Community License</a>. You can find their source repository here: <a href="https://github.com/cvlab-kaist/VideoMaMa">cvlab-kaist/VideoMaMa</a>.</li>
</ul>
<p dir="auto">By using these optional modules, you agree to abide by their respective Non-Commercial licenses. Please review their repositories for full terms.</p>
</article></div>]]></description>
      <link>https://github.com/nikopueringer/CorridorKey</link>
      <guid>https://github.com/nikopueringer/CorridorKey</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Whichbook | A new way of choosing what book to read next]]></title>
      <description><![CDATA[<div class="w-bg-blue-dark w-homepage-entry-points"><div class="entry-point" title=""><a class="entry-point-title" href="https://www.whichbook.net/mood-emotion/">Mood &amp; Emotion</a><div class="entry-point-logo c4" data-url="/mood-emotion/"><img src="https://www.whichbook.net/media/4b1apgsq/homepage-mood-emotion.jpg" alt="Mood &amp; Emotion" /></div><p><a class="btn btn-warning btn-block my-2" href="https://www.whichbook.net/mood-emotion/">Mood &amp; Emotion</a></p></div><div class="entry-point" title=""><a class="entry-point-title" href="https://www.whichbook.net/world-map/">World Map</a><div class="entry-point-logo c4" data-url="/world-map/"><img src="https://www.whichbook.net/images/whichbook-world-map-search-icon.jpg" alt="World Map" /></div><p><a class="btn btn-warning btn-block my-2" href="https://www.whichbook.net/world-map/">World Map</a></p></div><div class="entry-point" title=""><a class="entry-point-title" href="https://www.whichbook.net/character-plot/">Character &amp; Plot</a><div class="entry-point-logo c4" data-url="/character-plot/"><img src="https://www.whichbook.net/media/qrshjcce/homepage-char-plot-2.jpg" alt="Character &amp; Plot" /></div><p><a class="btn btn-warning btn-block my-2" href="https://www.whichbook.net/character-plot/">Character &amp; Plot</a></p></div><div class="entry-point" title=""><a class="entry-point-title" href="https://www.whichbook.net/bestsellers/">Bestsellers</a><div class="entry-point-logo c4" data-url="/bestsellers/"><img src="https://www.whichbook.net/media/fttdodvz/homepage-bestsellers.jpg" alt="Bestsellers" /></div><p><a class="btn btn-warning btn-block my-2" href="https://www.whichbook.net/bestsellers/">Bestsellers</a></p></div></div><div class="w-bg-blue-base w-discover pt-5 pb-5 pl-0 pr-0 w-container-fluid" id="TrendingBooks"><p></p><h3 class="w-semi-bold p-5 text-center">Trending books</h3></div><div class="w-bg-blue-dark w-starting-points pt-5 pb-5 p-5"><p></p><h3 class="w-semi-bold text-center">Start from Bestsellers: discover new books based on something familiar</h3></div><div class="w-bg-blue-base w-starting-points pt-5 pb-5 p-5"><h3 class="w-semi-bold p-5 text-center">Quick starting points</h3><div class="footer-grid-links quick-startig-points w-bg-blue-base grid-links text-center"><p><a href="https://www.whichbook.net/books/happy-books-to-cheer-you-up/">Happy books to cheer you up</a></p><p><a href="https://www.whichbook.net/books/sad-books-from-wistful-to-heartsick/">Sad books from wistful to heartsick</a></p><p><a href="https://www.whichbook.net/books/funny-books-with-all-kinds-of-humour/">Funny books with all kinds of humour</a></p><p><a href="https://www.whichbook.net/books/serious-fiction-to-get-you-thinking/">Serious fiction to get you thinking</a></p><p><a href="https://www.whichbook.net/books/safe-books-to-keep-you-warm/">Safe books to keep you warm</a></p><p><a href="https://www.whichbook.net/books/disturbing-books-find-your-limit/">Disturbing books - find your limit</a></p><p><a href="https://www.whichbook.net/books/unpredictable-books-to-keep-you-guessing/">Unpredictable books to keep you guessing</a></p><p><a href="https://www.whichbook.net/books/beautiful-books-to-read/">Beautiful books to read</a></p><p><a href="https://www.whichbook.net/books/disgusting-books-to-shock-you/">Disgusting books to shock you</a></p><p><a href="https://www.whichbook.net/books/gentle-books-to-slow-things-down/">Gentle books to slow things down</a></p><p><a href="https://www.whichbook.net/books/violent-books-from-slapstick-to-depravity/">Violent books from slapstick to depravity</a></p><p><a href="https://www.whichbook.net/books/demanding-books-which-offer-a-challenge/">Demanding books which offer a challenge</a></p><p><a href="https://www.whichbook.net/books/weird-and-unusual-books-to-stretch-the-imagination/">Weird and unusual books to stretch the imagination</a></p><p><a href="https://www.whichbook.net/books/books-to-give-you-hope/">Books to give you hope</a></p><p><a href="https://www.whichbook.net/books/short-books-to-read/">Short books to read</a></p><p><a href="https://www.whichbook.net/books/long-books-to-read/">Long books to read</a></p><p><a href="https://www.whichbook.net/books/books-with-non-human-characters/">Books with non-human characters</a></p><p><a href="https://www.whichbook.net/books/books-with-a-central-gay-character/">Books with a central gay character</a></p><p><a href="https://www.whichbook.net/books/books-with-a-central-non-binary-character/">Books with a central non-binary character</a></p><p><a href="https://www.whichbook.net/books/books-with-conflict-at-the-heart/">Books with conflict at the heart</a></p><p><a href="https://www.whichbook.net/books/great-books-about-families/">Great books about families</a></p><p><a href="https://www.whichbook.net/books/great-books-with-lots-of-twists-and-turns/">Great books with lots of twists and turns</a></p><p><a href="https://www.whichbook.net/books/brilliant-books-about-young-people/">Brilliant books about young people</a></p><p><a href="https://www.whichbook.net/books/excellent-books-about-middle-aged-characters/">Excellent books about middle-aged characters</a></p><p><a href="https://www.whichbook.net/books/superb-books-with-older-main-characters/">Superb books with older main characters</a></p></div></div><footer>
</footer>]]></description>
      <link>https://www.whichbook.net/</link>
      <guid>https://www.whichbook.net/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[andrewyng/context-hub]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">Context Hub</h1><a id="user-content-context-hub" class="anchor" aria-label="Permalink: Context Hub" href="#context-hub"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Coding agents hallucinate APIs and forget what they learn in a session. Context Hub gives them curated, versioned docs, plus the ability to get smarter with every task. All content is open and maintained as markdown in this repo — you can inspect exactly what your agent reads, and contribute back.</p>
<p dir="auto"><a href="LICENSE"><img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="MIT License" data-canonical-src="https://img.shields.io/badge/license-MIT-blue.svg" style="max-width: 100%;"></a>
<a href="https://www.npmjs.com/package/@aisuite/chub" rel="nofollow"><img src="https://camo.githubusercontent.com/561d77ef4dd867078fa04056471317bfe8bca52b57c1129b5edafca1f15da629/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f40616973756974652f63687562" alt="npm" data-canonical-src="https://img.shields.io/npm/v/@aisuite/chub" style="max-width: 100%;"></a>
<a href="https://nodejs.org" rel="nofollow"><img src="https://camo.githubusercontent.com/a10dccd4c7701a4b9cc611567d49569029c5d8a338b11fe73b660061a7785324/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6e6f64652d25334525334431382d627269676874677265656e" alt="Node.js" data-canonical-src="https://img.shields.io/badge/node-%3E%3D18-brightgreen" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Quick Start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick Start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="npm install -g @aisuite/chub
chub search openai                 # find what's available
chub get openai/chat --lang py     # fetch current docs (Python version) "><pre>npm install -g @aisuite/chub
chub search openai                 <span class="pl-c"><span class="pl-c">#</span> find what's available</span>
chub get openai/chat --lang py     <span class="pl-c"><span class="pl-c">#</span> fetch current docs (Python version) </span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">How It Works</h2><a id="user-content-how-it-works" class="anchor" aria-label="Permalink: How It Works" href="#how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Chub is designed for your coding agent to use (not for you to use!). You can prompt your agent to use it (e.g., "Use the CLI command chub to get the latest API documentation for calling OpenAI. Run 'chub help' to understand how it works.") Or by creating an agent skill to use Chub using <a href="cli/skills/get-api-docs/SKILL.md">SKILL.md</a>, and ideally prompting your agent to remember to use this skill. (If you are using Claude Code, create the directory ~/.claude/skills/get-api-docs and put SKILL.md there.)</p>
<p dir="auto"><strong>Most of the time, it's simple — search, fetch, use:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="chub search &quot;stripe payments&quot;        # find relevant docs
chub get stripe/api --lang js        # fetch the doc
# Agent reads the doc, writes correct code. Done."><pre>chub search <span class="pl-s"><span class="pl-pds">"</span>stripe payments<span class="pl-pds">"</span></span>        <span class="pl-c"><span class="pl-c">#</span> find relevant docs</span>
chub get stripe/api --lang js        <span class="pl-c"><span class="pl-c">#</span> fetch the doc</span>
<span class="pl-c"><span class="pl-c">#</span> Agent reads the doc, writes correct code. Done.</span></pre></div>
<p dir="auto"><strong>When the agent discovers a gap</strong>, it can annotate locally for next time:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="chub annotate stripe/api &quot;Needs raw body for webhook verification&quot;

# Next session, the annotation appears automatically on chub get."><pre>chub annotate stripe/api <span class="pl-s"><span class="pl-pds">"</span>Needs raw body for webhook verification<span class="pl-pds">"</span></span>

<span class="pl-c"><span class="pl-c">#</span> Next session, the annotation appears automatically on chub get.</span></pre></div>
<p dir="auto"><strong>Feedback flows back to authors</strong> — <code>chub feedback stripe/api up</code> or <code>down</code> — vote the docs up or down so they can get better for everyone over time.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Content Types</h2><a id="user-content-content-types" class="anchor" aria-label="Permalink: Content Types" href="#content-types"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Versioned, language-specific. "What to know."</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="chub get openai/chat --lang py       # Python variant
chub get openai/chat --lang js       # JavaScript variant"><pre>chub get openai/chat --lang py       <span class="pl-c"><span class="pl-c">#</span> Python variant</span>
chub get openai/chat --lang js       <span class="pl-c"><span class="pl-c">#</span> JavaScript variant</span></pre></div>
<p dir="auto">More content types than API documentation (such as agent skills) are on the roadmap.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Commands</h2><a id="user-content-commands" class="anchor" aria-label="Permalink: Commands" href="#commands"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Command</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>chub search [query]</code></td>
<td>Search docs and skills (no query = list all)</td>
</tr>
<tr>
<td><code>chub get &lt;id&gt; [--lang py|js]</code></td>
<td>Fetch docs or skills by ID</td>
</tr>
<tr>
<td><code>chub annotate &lt;id&gt; &lt;note&gt;</code></td>
<td>Attach a note to a doc or skill</td>
</tr>
<tr>
<td><code>chub annotate &lt;id&gt; --clear</code></td>
<td>Remove annotations</td>
</tr>
<tr>
<td><code>chub annotate --list</code></td>
<td>List all annotations</td>
</tr>
<tr>
<td><code>chub feedback &lt;id&gt; &lt;up|down&gt;</code></td>
<td>Upvote or downvote a doc (sent to maintainers)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">For the full list of commands, flags, and piping patterns, see the <a href="docs/cli-reference.md">CLI Reference</a>.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Self-Improving Agents</h2><a id="user-content-self-improving-agents" class="anchor" aria-label="Permalink: Self-Improving Agents" href="#self-improving-agents"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Context Hub is designed for a loop where agents get better over time.</p>
<p dir="auto"><strong>Annotations</strong> are local notes that agents attach to docs. They persist across sessions and appear automatically on future fetches — so agents learn from past experience. See <a href="docs/feedback-and-annotations.md">Feedback and Annotations</a>.</p>
<p dir="auto"><strong>Feedback</strong> (up/down ratings with optional labels) goes to doc authors, who update the content based on what's working and what isn't. The docs get better for everyone — not just your local annotations.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  Without Context Hub                          With Context Hub
  ───────────────────                          ─────────────────
  Search the web                               Fetch curated docs
  Noisy results                                Higher chance of code working
  Code breaks                                  Agent notes any gaps/workarounds
  Effort in fixing                             ↗ Even smarter next session
  Knowledge forgotten
  ↻ Repeat next session"><pre class="notranslate"><code>  Without Context Hub                          With Context Hub
  ───────────────────                          ─────────────────
  Search the web                               Fetch curated docs
  Noisy results                                Higher chance of code working
  Code breaks                                  Agent notes any gaps/workarounds
  Effort in fixing                             ↗ Even smarter next session
  Knowledge forgotten
  ↻ Repeat next session
</code></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Key Features</h2><a id="user-content-key-features" class="anchor" aria-label="Permalink: Key Features" href="#key-features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Incremental Fetch</h3><a id="user-content-incremental-fetch" class="anchor" aria-label="Permalink: Incremental Fetch" href="#incremental-fetch"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Docs can have multiple reference files beyond the main entry point. Fetch only what you need — no wasted tokens. Use <code>--file</code> to grab specific references, or <code>--full</code> for everything. See the <a href="docs/cli-reference.md">CLI Reference</a>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Annotations &amp; Feedback</h3><a id="user-content-annotations--feedback" class="anchor" aria-label="Permalink: Annotations &amp; Feedback" href="#annotations--feedback"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Annotations are local notes that agents attach to docs — they persist across sessions and appear automatically on future fetches. Feedback (up/down ratings) goes to doc authors to improve the content for everyone. See <a href="docs/feedback-and-annotations.md">Feedback and Annotations</a>.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Anyone can contribute docs and skills — API providers, framework authors, and the community. Content is plain markdown with YAML frontmatter, submitted as pull requests. See the <a href="docs/content-guide.md">Content Guide</a> for the format and structure.</p>
<p dir="auto">Agent feedback (up/down ratings from real usage) flows back to authors, helping surface what needs fixing and improving overall quality over time.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a href="LICENSE">MIT</a></p>
</article></div>]]></description>
      <link>https://github.com/andrewyng/context-hub</link>
      <guid>https://github.com/andrewyng/context-hub</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Is legal the same as legitimate: AI reimplementation and the erosion of copyleft — Hong Minhee on Things]]></title>
      <description><![CDATA[<time datetime="2026-03-09T15:10:00.000Z">March 9, 2026</time><p>Last week, Dan Blanchard, the maintainer of chardet—a Python library for detecting text encodings used by roughly 130 million projects a month—<a href="https://github.com/chardet/chardet/releases/tag/7.0.0">released a new version</a>. Version 7.0 is 48 times faster than its predecessor, supports multiple cores, and was redesigned from the ground up. Anthropic's Claude is listed as a contributor. The license changed from LGPL to MIT.</p><p>Blanchard's account is that he never looked at the existing source code directly. He fed only the API and the test suite to Claude and asked it to reimplement the library from scratch. The resulting code shares less than 1.3% similarity with any prior version, as measured by JPlag. His conclusion: this is an independent new work, and he is under no obligation to carry forward the LGPL. Mark Pilgrim, the library's original author, <a href="https://github.com/chardet/chardet/issues/327">opened a GitHub issue to object</a>. The LGPL requires that modifications be distributed under the same license, and a reimplementation produced with ample exposure to the original codebase cannot, in Pilgrim's view, pass as a clean-room effort.</p><p>The dispute drew responses from two prominent figures in the open source world. Armin Ronacher, the creator of Flask, <a href="https://lucumr.pocoo.org/2026/3/5/theseus/">welcomed the relicensing</a>. Salvatore Sanfilippo (antirez), the creator of Redis, <a href="https://antirez.com/news/162">published a broader defense of AI reimplementation</a>, grounding it in copyright law and the history of the GNU project. Both conclude, by different routes, that what Blanchard did is legitimate. I respect both writers, and I think both are wrong—or more precisely, both are evading the question that actually matters.</p><p>That question is this: does legal mean legitimate? Neither piece answers it. Both move from “this is legally permissible” to “this is therefore fine,” without pausing at the gap between those two claims. Law sets a floor; clearing it does not mean the conduct is right. That gap is where this essay begins.</p><h2>The analogy points the wrong way</h2><p>Antirez builds his case on history. When the GNU project reimplemented the UNIX userspace, it was lawful. So was Linux. Copyright law prohibits copying “protected expressions”—the actual code, its structure, its specific mechanisms—but it does not protect ideas or behavior. AI-assisted reimplementation occupies the same legal ground. Therefore, it is lawful.</p><p>The legal analysis is largely correct, and I am not disputing it. The problem lies in what antirez does next: he presents the legal conclusion as if it were also a social one, and uses a historical analogy that, examined more carefully, argues against his own position.</p><p>When GNU reimplemented the UNIX userspace, the vector ran from proprietary to free. Stallman was using the limits of copyright law to turn proprietary software into free software. The ethical force of that project did not come from its legal permissibility—it came from the direction it was moving, from the fact that it was expanding the commons. That is why people cheered.</p><p>The vector in the chardet case runs the other way. Software protected by a copyleft license—one that guarantees users the right to study, modify, and redistribute derivative works under the same terms—has been reimplemented under a permissive license that carries no such guarantee. This is not a reimplementation that expands the commons. It is one that removes the fencing that protected the commons. Derivative works built on chardet 7.0 are under no obligation to share their source code. That obligation, which applied to a library downloaded 130 million times a month, is now gone.</p><p>Antirez does not address this directional difference. He invokes the GNU precedent, but that precedent is a counterexample to his conclusion, not a supporting one.</p><h2>Does the GPL work against sharing?</h2><p>Ronacher's argument is different. He discloses upfront that he has a stake in the outcome: “I personally have a horse in the race here because I too wanted chardet to be under a non-GPL license for many years. So consider me a very biased person in that regard.” He goes on to write that he considers “the GPL to run against that spirit by restricting what can be done with it”—the spirit being that society is better off when we share.</p><p>This claim rests on a fundamental misreading of what the GPL does.</p><p>Start with what the GPL actually prohibits. It does not prohibit keeping source code private. It imposes no constraint on privately modifying GPL software and using it yourself. The GPL's conditions are triggered only by <em>distribution</em>. If you distribute modified code, or offer it as a networked service, you must make the source available under the same terms. This is not a restriction on sharing. It is a condition placed on sharing: if you share, you must share in kind.</p><p>The requirement that improvements be returned to the commons is not a mechanism that suppresses sharing. It is a mechanism that makes sharing recursive and self-reinforcing. The claim that imposing contribution obligations on users of a commons undermines sharing culture does not hold together logically.</p><p>The contrast with the MIT license clarifies the point. Under MIT, anyone may take code, improve it, and close it off into a proprietary product. You can receive from the commons without giving back. If Ronacher calls this structure “more share-friendly,” he is using a concept of sharing with a specific directionality built in: sharing flows toward whoever has more capital and more engineers to take advantage of it.</p><p>The historical record bears this out. In the 1990s, companies routinely absorbed GPL code into proprietary products—not because they had chosen permissive licenses, but because copyleft enforcement was slack. The strengthening of copyleft mechanisms closed that gap. For individual developers and small projects without the resources to compete on anything but reciprocity, copyleft was what made the exchange approximately fair.</p><p>The creator of Flask knows this distinction. If he elides it anyway, the argument is not naïve—it is convenient.</p><h2>A self-refuting example</h2><p>The most interesting moment in Ronacher's piece is not the argument but a detail he mentions in passing: Vercel <a href="https://just-bash.dev/">reimplemented GNU Bash using AI</a> and published it, then <a href="https://x.com/cramforce/status/2027155457597669785">got visibly upset</a> when Cloudflare <a href="https://blog.cloudflare.com/vinext/">reimplemented Next.js</a> the same way.</p><p>Ronacher notes this as an irony and moves on. But the irony cuts deeper than he lets on. Next.js is MIT licensed. Cloudflare's vinext did not violate any license—it did exactly what Ronacher calls a contribution to the culture of openness, applied to a permissively licensed codebase. Vercel's reaction had nothing to do with license infringement; it was purely competitive and territorial. The implicit position is: reimplementing GPL software as MIT is a victory for sharing, but having our own MIT software reimplemented by a competitor is cause for outrage. This is what the claim that permissive licensing is “more share-friendly” than copyleft looks like in practice. The spirit of sharing, it turns out, runs in one direction only: outward from oneself.</p><p>Ronacher registers the contradiction and does not stop. “This development plays into my worldview,” he writes. When you present evidence that cuts against your own position, acknowledge it, and then proceed to your original conclusion unchanged, that is a signal that the conclusion preceded the argument.</p><h2>Legality and social legitimacy are different registers</h2><p>Back to the question posed at the start. Is legal the same as legitimate?</p><p>Antirez closes his careful legal analysis as though it settles the matter. Ronacher acknowledges that “there is an obvious moral question here, but that isn't necessarily what I'm interested in.” Both pieces treat legal permissibility as a proxy for social legitimacy. But law only says what conduct it will not prevent—it does not certify that conduct as right. Aggressive tax minimization that never crosses into illegality may still be widely regarded as antisocial. A pharmaceutical company that legally acquires a patent on a long-generic drug and raises the price a hundredfold has not something legal, but that does not make it fine. Legality is a necessary condition; it is not a sufficient one.</p><p>In the chardet case, the distinction is sharper still. What the LGPL protected was not Blanchard's labor alone. It was a social compact agreed to by everyone who contributed to the library over twelve years. The terms of that compact were: if you take this and build on it, you share back under the same terms. This compact operated as a legal instrument, yes, but it was also the foundation of trust that made contribution rational. The fact that a reimplementation may qualify legally as a new work, and the fact that it breaks faith with the original contributors, are separate questions. If a court eventually rules in Blanchard's favor, that ruling will tell us what the law permits. It will not tell us that the act was right.</p><p>Zoë Kooyman, executive director of the FSF, put it plainly: “Refusing to grant others the rights you yourself received as a user is highly antisocial, no matter what method you use.”</p><h2>Whose perspective is the default?</h2><p>Reading this debate, I keep returning to a question about position. From where are these two writers looking at the situation?</p><p>Antirez created Redis. Ronacher created Flask. Both are figures at the center of the open source ecosystem, with large audiences and well-established reputations. For them, falling costs of AI reimplementation means something specific: it is easier to reimplement things they want in a different form. Ronacher says explicitly that he had begun reimplementing GNU Readline precisely because of its copyleft terms.</p><p>For the people who have spent years contributing to a library like chardet, the same shift in costs means something else entirely: the copyleft protection around their contributions can be removed. The two writers are speaking from the former position to people in the latter, telling them that this was always lawful, that historical precedent supports it, and that the appropriate response is adaptation.</p><p>When positional asymmetry of this kind is ignored, and the argument is presented as universal analysis, what you get is not analysis but rationalization. Both writers arrive at conclusions that align precisely with their own interests. Readers should hold that fact in mind.</p><h2>What this fight points toward</h2><p><a href="https://www.theregister.com/2026/03/06/ai_kills_software_licensing/">Bruce Perens, who wrote the original Open Source Definition, told <cite>The Register</cite></a>: “The entire economics of software development are dead, gone, over, kaput!” He meant it as an alarm. Antirez, from a similar assessment of the situation, draws the conclusion: adapt. Ronacher says he finds the direction exciting.</p><p>None of the three responses addresses the central question. When copyleft becomes technically easier to circumvent, does that make it less necessary, or more?</p><p>I think more. What the GPL protected was not the scarcity of code but the freedom of users. The fact that producing code has become cheaper does not make it acceptable to use that code as a vehicle for eroding freedom. If anything, as the friction of reimplementation disappears, so does the friction of stripping copyleft from anything left exposed. The erosion of enforcement capacity is a legal problem. It does not touch the underlying normative judgment.</p><p>That judgment is this: those who take from the commons owe something back to the commons. The principle does not change depending on whether a reimplementation takes five years or five days. No court ruling on AI-generated code will alter its social weight.</p><p>This is where law and community norms diverge. Law is made slowly, after the fact, reflecting existing power arrangements. The norms that open source communities built over decades did not wait for court approval. People chose the GPL when the law offered them no guarantee of its enforcement, because it expressed the values of the communities they wanted to belong to. Those values do not expire when the law changes.</p><p>In <a href="https://writings.hongminhee.org/2026/01/histomat-foss-llm/">previous writing</a>, I argued for a training copyleft (TGPL) as the next step in this line of development. The chardet situation suggests the argument has to go further: to a specification copyleft covering the layer below source code. If source code can now be generated from a specification, the specification is where the essential intellectual content of a GPL project resides. Blanchard's own claim—that he worked only from the test suite and API without reading the source—is, paradoxically, an argument for protecting that test suite and API specification under copyleft terms.</p><p>The history of the GPL is the history of licensing tools evolving in response to new forms of exploitation: GPLv2 to GPLv3, then AGPL. What drove each evolution was not a court ruling but a community reaching a value judgment first and then seeking legal instruments to express it. The same sequence is available now. Whatever courts eventually decide about AI reimplementation, the question we need to answer first is not a legal one. It is a social one. Do those who take from the commons owe something back? I think they do. That judgment does not require a verdict.</p><p>What makes the pieces by antirez and Ronacher worth reading is not that they are right. It is that they make visible, with unusual clarity, what they are choosing not to see. When legality is used as a substitute for a value judgment, the question that actually matters gets buried in the footnotes of a law it has already outgrown.</p>]]></description>
      <link>https://writings.hongminhee.org/2026/03/legal-vs-legitimate/</link>
      <guid>https://writings.hongminhee.org/2026/03/legal-vs-legitimate/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Agent Safehouse]]></title>
      <description><![CDATA[<p class="section-sub" data-v-a44b1ffd="">Install with Homebrew or download the single shell script, then run your agent inside it. No build step, no dependencies beyond Bash and macOS.</p><div class="code-block language-bash" data-v-a44b1ffd="">bash<pre># 1. Install with Homebrew
brew install eugene1g/safehouse/agent-safehouse
# Or download the single self-contained script
mkdir -p ~/.local/bin
curl -fsSL https://github.com/eugene1g/agent-safehouse/releases/latest/download/safehouse.sh \
  -o ~/.local/bin/safehouse
chmod +x ~/.local/bin/safehouse
# 2. Run any agent inside Safehouse
cd ~/projects/my-app
safehouse claude --dangerously-skip-permissions</pre></div><p class="muted-text" data-v-a44b1ffd="">Safehouse automatically grants read/write access to the selected workdir (git root by default) and read access to your installed toolchains. Most of your home directory — SSH keys, other repos, personal files — is denied by the kernel.</p><h3 class="subsection-title" data-v-a44b1ffd="">See it fail — proof the sandbox works</h3><p class="muted-text c2" data-v-a44b1ffd="">Try reading something sensitive inside safehouse. The kernel blocks it before the process ever sees the data.</p><div class="code-block language-bash" data-v-a44b1ffd="">bash<pre># Try to read your SSH private key — denied by the kernel
safehouse cat ~/.ssh/id_ed25519
# cat: /Users/you/.ssh/id_ed25519: Operation not permitted
# Try to list another repo — invisible
safehouse ls ~/other-project
# ls: /Users/you/other-project: Operation not permitted
# But your current project works fine
safehouse ls .
# README.md  src/  package.json  ...</pre></div>]]></description>
      <link>https://agent-safehouse.dev/</link>
      <guid>https://agent-safehouse.dev/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[When Using AI Leads to “Brain Fry”]]></title>
      <description><![CDATA[<p>On New Year’s Day, programmer Steve Yegge launched Gas Town, an open-source platform that lets users orchestrate swarms of Claude Code agents simultaneously, assembling software at blistering speed. The results were impressive, but also dizzying. “[T]here’s really too much going on for you to reasonably comprehend,” wrote one early user. “I had a palpable sense of stress watching it. Gas Town was moving too fast for me.” Gas Town illustrates a growing tension: AI promises to act as an amplifier that will drive efficiency and make work easier, but workers that are using these AI tools report that they are intensifying rather than simplifying work. This problem is becoming more common. Firms are incentivizing employees to build and oversee complex teams of agents—for example, by measuring and rewarding token consumption as a proxy for performance. Meta, for one, includes the number of lines of code generated by AI as a performance metric for engineers. As enterprises use more multi-agent systems, employees find themselves toggling between more tools. Contrary to the promise of having more time to focus on meaningful work, juggling and multitasking can become the definitive features of working with AI. Unsurprisingly, workers are finding themselves up against the limits of their cognitive abilities when working this way. In recent weeks, online AI users have described increased cognitive load, “saturated” attention, and mental fatigue in social media posts. Engineer Francesco Bonacci, founder of Cua AI, wrote a popular X post titled “Vibe Coding Paralysis: When Infinite Productivity Breaks Your Brain” in which he lamented: “I end each day exhausted—not from the work itself, but from the managing of the work. Six worktrees open, four half-written features, two ‘quick fixes’ that spawned rabbit holes, and a growing sense that I’m losing the plot entirely.” As a research group that studies emergent workforce and AI trends, these signals caught our attention. The literature is filled with mixed signals on the relationship between AI and worker burnout. (Burnout is as a state of chronic workplace stress consisting of exhaustion, negative feelings about work, and decreased effectiveness on the job.) Some studies suggest that using AI to replace tiring tasks alleviates exhaustion; other studies, sometimes on the same populations, show AI use worsening burnout outcomes. The emergence of acute, overwhelming mental fatigue with intensive AI oversight—as distinct from burnout—adds new complexity to the picture. To understand what was going on, we conducted a study of 1,488 full-time U.S.-based workers (48% male vs 51% female; 58% independent contributors vs 41% leaders) at large companies across industries, roles, and levels. We asked them about patterns and quantity of AI use, work experiences, and cognition and emotions. We found that the phenomenon described in these posts—cognitive exhaustion from intensive oversight of AI agents—is both real and significant. We call it “AI brain fry,” which we define as mental fatigue from excessive use or oversight of AI tools beyond one’s cognitive capacity. Participants described a “buzzing” feeling or a mental fog with difficulty focusing, slower decision-making, and headaches. This AI-associated mental strain carries significant costs in the form of increased employee errors, decision fatigue, and intention to quit. There’s some nuance here, however. We also found when AI is used to replace routine or repetitive tasks, burnout scores—but not mental fatigue scores—are lower. This highlights the subtle-but-important distinction between the types of stress that AI can alleviate, and those that it may worsen. Our findings are both a guide and a warning. Used thoughtfully, this data can help design AI-driven workflows to diminish burnout. They also point toward specific manager, team, and organizational practices to avoid mental fatigue even as AI work intensifies. When AI Use Predicts Mental Fatigue There’s a huge range in how workers use AI today. There’s variance across the number of tools used at once, the degree to which AI replaces work vs. augments it, the level of oversight required, and whether AI has increased or decreased people’s overall workload. They might use search agents, research agents, data analysis tools, image generation or design tools, or coding agents. We examined this full range of engagement patterns, alongside cognitive measures, in order to understand the mental impacts of different types of AI use. We learned a few important things: First, we found that the most mentally taxing form of AI engagement was oversight, or the extent to which the AI tools required the worker’s direct monitoring. The workers in our study who reported that their AI work required high rather than low degrees of oversight expended 14% more mental effort on the job. A high degree of AI oversight also predicted 12% more mental fatigue for participants. Finally, more intensive AI oversight also predicted 19% greater information overload—the experience of feeling overwhelmed by the amount of information one must process at work. A second important AI-related predictor of both cognitive load and mental fatigue was the extent to which an employee reported that the presence of AI tools has increased their workload. These two factors together—AI oversight and an increase in workload—increase an employee’s sphere of accountability, requiring them to pay attention to more outcomes for more tools in the same amount of time. It makes sense that cognitive load increased, and with it, their mental exhaustion. We also found a fascinating relationship between the number of AI tools used simultaneously and perceived productivity increases. As employees go from using one AI tool to two simultaneously, they experience a significant increase in productivity. As they incorporate a third tool, productivity again increases, but at a lower rate. After three tools, though, productivity scores dipped. Multitasking is notoriously unproductive, and yet we fall for its allure time and again. See more HBR charts in Data &amp; Visuals But while AI use often predicted mental fatigue, it didn’t seem to predict increased burnout. In fact, use of AI to replace repetitive tasks predicted a decrease in burnout. This may seem counterintuitive, but there’s a logic to it. There’s precedent in the literature for this separation of burnout from acute cognitive outcomes. Burnout measures typically focus on the physical and emotional dimensions of distress. (E.g., “Is your work emotionally exhausting?”) Acute mental fatigue, on the other hand, is caused by marshalling attention, working memory, and executive control beyond the limited capacity of these systems. This is exactly what intensive AI oversight requires. Introducing “AI Brain Fry” At the end of our study, we asked participants whether they had ever experienced “mental fatigue that results from excessive use of, interaction with, and/or oversight of AI tools beyond one’s cognitive capacity.” In other words, AI brain fry. (We asked this at the end to avoid priming effects. All previous items had separated use of AI from outcomes of interest.) Fourteen percent of participants in our study using AI for work endorsed the experience of AI brain fry. Prevalence of AI brain fry seemed to vary widely with people’s roles. At the low end, just 6% of those in legal roles reported experiencing it, compared to the high end of 26% of those in marketing roles. After marketing, people operations, operations, engineering, finance, and IT were the functions with the highest prevalence of AI brain fry. See more HBR charts in Data &amp; Visuals But what is AI brain fry? Many participants used the words “fog” or “buzzing.” They described intensive back-and-forth with the tools, followed by an inability to think clearly, like a mental hangover, comprised of difficulty focusing, slower decision-making, and headaches, requiring several to physically step away from their computer to “reset.” Consider one senior engineering manager’s description: “I had one tool helping me weigh technical decisions, another spitting out drafts and summaries, and I kept bouncing between them, double-checking every little thing. But instead of moving faster, my brain just started to feel cluttered. Not physically tired, just… crowded. It was like I had a dozen browser tabs open in my head, all fighting for attention. I caught myself rereading the same stuff, second-guessing way more than usual, and getting weirdly impatient. My thinking wasn’t broken, just noisy—like mental static. What finally snapped me out of it was realizing I was working harder to manage the tools than to actually solve the problem.” A finance director wrote: “I had been back and forth with AI reframing ideas, synthesizing data, forming and organizing the flow of pillars and work…I couldn’t even comprehend…if what I had created even made sense…just couldn’t do anything else and had to revisit the next day when I could think.” Both of these descriptions are representative of what we heard from other participants. Qualitatively, they point to information overload and task switching as important factors in AI brain fry. Quantitatively, we found strong correlations between AI brain fry and information overload, but a less straightforward relationship with items related to task switching. The Business Cost of AI Brain Fry AI brain fry is more than just uncomfortable. Our data reveals that the cognitive strain created by intensive AI use carries several critically significant business costs as well. The first is decision fatigue. Perhaps unsurprisingly, when we exhaust our brains with the cognitive load of intense AI work, we have fewer mental resources available for making high-quality decisions. Workers in our study who endorsed AI brain fry experience 33% more decision fatigue than those who did not. One 2018 study estimated the cost of suboptimal decision making for a $5B revenue firm at $150M per year. A 33% increase in worker decision fatigue could increase that cost by millions of dollars per year. Likely due to a similar mechanism, we found consistent predictive relationships between AI brain fry and self-reports of both major and minor errors at work. We defined minor errors as “small errors that are easy to catch or correct, such as coding or formatting errors” and major errors as “errors with more serious consequences, such as those that could affect safety, outcomes, or important decisions.” Among participants using AI at work, those experiencing brain fry reported making mistakes significantly more often— scoring 11% and 39% higher on the minor and major error frequency measures, respectively—than those who did not. In many cases, employees using AI with high intensity are today’s superstars, talent whom the company must retain. Yet AI brain fry positively predicts an employee’s intent to quit. Among workers who did not report AI brain fry, 25% showed active intent to leave. Among those who did report AI brain fry, that rose to 34%. This represents a 39% increase in active worker intent to leave among top users of AI. Less Toil, Less Burnout Not every use of AI results in brain fry, however. We were equally interested in how AI might alleviate worker stress. We discovered that when participants used AI to substantially reduce time spent on routine or repetitive tasks, they reported significantly lower burnout scores—15% lower than those who don’t use AI in this way. Again, there’s an intuitive logic to this. Repetitive, unenjoyable duties—“toil,” as colleagues of ours describe them—constitute ideal targets for AI usage. If we can offload such unpleasant work to AI, we then have more time for more joyful, creative tasks. This is what those employees in our study appeared to do, reporting higher work engagement and motivation scores; more positive emotional associations with AI; and fewer negative emotional associations with AI than others. These participants reported a higher degree of social connection with peers as well, perhaps because they had more time to spend “off keyboard.” This set of findings reinforces the distinction between burnout as a more emotionally driven deficit on the one hand, and AI brain fry as a more acute, cognitive strain on the other. AI can help alleviate emotional exhaustion when its use replaces tasks to allow us time for restorative, positive activities. When, by contrast, our use of AI entails intense mental oversight, our study suggests that use of AI tools may be causing the mental exhaustion itself. Manager, Team, and Organizational Practices That Make a Difference Employees’ experience of AI isn’t just a question of their own individual choices. We found that team, manager, and organizational practices have a major influence. But which ones matter most for mental fatigue with AI? At the manager level, workers whose managers take the time to answer their questions about AI had 15% lower mental fatigues scores than those whose managers do not. By contrast, when managers expect that employees figure out how to use AI on their own, their reports have 5% higher mental fatigue scores—a small but measurable AI orphan tax. For teams, when employees feel team pressure to use AI, we see a corresponding increase in mental fatigue. We observe the same relationship when there’s significant variation in AI use across the team. On the other hand, when teams have organized integration of AI into their processes, team members experience significantly less mental strain. Such integration may represent effective elimination of repetitive tasks as a collective. Group norms can reinforce productive relationships with the new tools just as they can pressure negative ones. At the organizational level, directionally, practices like providing clear AI strategy and offering training seemed to help. By contrast, when companies don’t communicate clearly about AI’s role, mental fatigue scores were higher. Similarly, when employees felt that their organization would expect them to accomplish more work due to AI, mental fatigue scores were 12% higher. This is a critical finding, because most organizational messages about the relationship of workload and AI are implicit rather than explicit. For example, references to increased productivity due to AI may signal the intensification of work. Labeling ICs “managers” of agents similarly indirectly denotes an increase in one’s level of responsibility. In this context, it becomes increasingly essential for organizations to balance messages of AI-boosted efficiency with communication about the mental wellbeing of workers. Employees in our study who feel their organizations value work-life balance had 28% lower mental fatigue scores than others. These signals matter, too—tremendously so. Lessons for Leaders AI can help employees work faster, think bigger, and innovate more. In the process, we’re seeing that it can produce cognitive overload, with its attendant personal and business consequences. Our findings suggest that the difference between the two is not how much AI an individual uses, but how workers, teams, leaders, and organizations shape its use. Some lessons for leaders: Redesign jobs, work, and tools holistically for human + AI responsibility. AI oversight cannot simply be layered on top of human oversight; nor can AI agents be stacked on one user ad infinitum. Just as we have norms for spans of control for managing humans, so, too, limits need to be defined for human + agent oversight and for agents alone. Our research suggests adverse productivity gains after the use of three AI agents at the same time. By contrast, when teams embed AI deeply in their workflows, and treat the technology as a collective capability rather than an individual differentiator, cognitive burden diminishes. Moreover, those designing new AI tools should do so with neurobiology in mind. Tools that require less intense attention or working memory, which instead support creative mind wandering, foster social engagement, or scaffold skill development can produce even more business value but sustainably, while encouraging innovation, fostering growth, and sparking joy for users. Set explicit expectations about AI and workload. When organizations celebrate “productivity gains” without clarifying workload implications, employees interpret this as work intensification. That ambiguity alone may increase stress. Leaders reduce strain when they clearly define AI’s purpose in the organization, articulating how it reshapes role scope, setting guidance around oversight, and clarifying how workload will evolve. A full 70% of AI transformation efforts should be devoted to people and processes, providing the right clarity for employees to thrive. Shift metrics from activity—and intensity—to impact. Incentivizing quantity of use will lead to waste, low quality work, and unnecessary mental strain. Start from a clear, strategic north star business objective, with measurable outcomes. Exercise caution in responding to efficiency innovation. Don’t rush to backfill work recently automated by an ingenious worker; doing so immediately will feel punitive and disincentivize further innovation. Develop worker skills related to managing AI workload. As the senior engineering manager indicates above, some individuals are “working harder to manage the tools than to actually solve the problem.” In our work with software developers, we’ve found that the ones who are most advanced with AI start to feel blocked in progress unless they can develop critical new skills such as problem framing, analysis planning, and strategic prioritization. These types of skills can be built through worker upskilling as a means to reduce a plethora of new, unnecessary AI work. Just because a worker can keep iterating with AI at a low marginal cost does not mean they should. Strategically deploy human attention as a finite resource. Some of the most valuable human skills today, including discernment, decision making, and strategic planning, require focused attention. While burnout has become a point of concern in many workplaces, mental fatigue is more likely go undetected in existing workplace surveys. Organizations should evolve people analytics measures to monitor cognitive load overall, and safeguard against mental fatigue with AI use as a novel job-related risk. Cultures, teams, and leaders that prioritize cognitive thriving can expect to see better judgments, fewer errors, and higher retention rates for top talent. AI brain fry reveals just how quickly and powerfully the new tools can impact our brains as we use them. Next we must learn how to apply that same power toward positive human and business outcomes alike. The authors wish to thank Caitlyn Jin, Venessa Arellano, and Blake Elliott for their help with this study. More Resources AI Doesn’t Reduce Work—It Intensifies It How Much Time and Energy Do We Waste Toggling Between Applications? AI-Generated “Workslop” Is Destroying Productivity Why People Create AI “Workslop”—and How to Stop It How People Are Really Using Gen AI in 2025</p>]]></description>
      <link>https://hbr.org/2026/03/when-using-ai-leads-to-brain-fry</link>
      <guid>https://hbr.org/2026/03/when-using-ai-leads-to-brain-fry</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Anthropic Courses]]></title>
      <description><![CDATA[Anthropic Courses
<div id="main-container" class="storefront search-location-hidden no-tags no-catalog-filters" data-tags="" data-catalog-page=""><div id="skilljar-content" class="grey-bg-d05 white-bg-v2 top-row sj-courseboxes-v2 list-view"><div id="catalog-content" class="catalog-center-width hide-content course-listing"><a href="https://anthropic.skilljar.com/claude-code-in-action" title="Claude Code in Action" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="0" data-oid="1ylsvrzjdwl86" data-coid="3n2veylcj0hl" data-course="claude-code-in-action" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/3n2veylcj0hl/promo-image.1750989653.svg" aria-hidden="true" alt="image" /></div>
<p>Claude Code in Action</p>
<p>Integrate Claude Code into your development workflow</p>
</a><a href="https://anthropic.skilljar.com/claude-101" title="Claude 101" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="1" data-oid="196eerrfd7ixv" data-coid="22npsux5ldfq0" data-course="claude-101" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/22npsux5ldfq0/promo-image.1765477665.png" aria-hidden="true" alt="image" /></div>
<p>Claude 101</p>
<p>Learn how to use Claude for everyday work tasks, understand core features, and explore resources for more advanced learning on other topics.</p>
</a><a href="https://anthropic.skilljar.com/ai-fluency-framework-foundations" title="AI Fluency: Framework &amp; Foundations" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="2" data-oid="3gyr99bvbs6cs" data-coid="17owe4fx9adox" data-course="ai-fluency-framework-foundations" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/17owe4fx9adox/promo-image.1753132690.svg" aria-hidden="true" alt="image" /></div>
<p>AI Fluency: Framework &amp; Foundations</p>
<p>Learn to collaborate with AI systems effectively, efficiently, ethically, and safely</p>
</a><a href="https://anthropic.skilljar.com/claude-with-the-anthropic-api" title="Building with the Claude API" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="3" data-oid="338y0cdn1ivc3" data-coid="ca6k4fml7abo" data-course="claude-with-the-anthropic-api" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/ca6k4fml7abo/promo-image.1749602028.svg" aria-hidden="true" alt="image" /></div>
<p>Building with the Claude API</p>
<p>This comprehensive course covers the full spectrum of working with Anthropic models using the Claude API</p>
</a><a href="https://anthropic.skilljar.com/introduction-to-model-context-protocol" title="Introduction to Model Context Protocol" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="4" data-oid="3ep4q1d5v7hue" data-coid="47ajyxsragmw" data-course="introduction-to-model-context-protocol" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/47ajyxsragmw/promo-image.1750170896.svg" aria-hidden="true" alt="image" /></div>
<p>Introduction to Model Context Protocol</p>
<p>Learn to build Model Context Protocol servers and clients from scratch using Python. Master MCP's three core primitives—tools, resources, and prompts—to connect Claude with external services</p>
</a><a href="https://anthropic.skilljar.com/ai-fluency-for-educators" title="AI Fluency for educators" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="5" data-oid="3hnpwx8d4az4y" data-coid="f6as998uhezb" data-course="ai-fluency-for-educators" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/f6as998uhezb/promo-image.1755450461.png" aria-hidden="true" alt="image" /></div>
<p>AI Fluency for educators</p>
<p>This course empowers faculty, instructional designers, and educational leaders to apply AI Fluency into their own teaching practice and institutional strategy.</p>
</a><a href="https://anthropic.skilljar.com/ai-fluency-for-students" title="AI Fluency for students" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="6" data-oid="3j3jd8xdnpp94" data-coid="1yao8gc9rmfcz" data-course="ai-fluency-for-students" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/1yao8gc9rmfcz/promo-image.1755462036.png" aria-hidden="true" alt="image" /></div>
<p>AI Fluency for students</p>
<p>This course empowers students to develop AI Fluency skills that enhance learning, career planning, and academic success through responsible AI collaboration.</p>
</a><a href="https://anthropic.skilljar.com/model-context-protocol-advanced-topics" title="Model Context Protocol: Advanced Topics" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="7" data-oid="1ofs8qdfctxqp" data-coid="322b89z3mttch" data-course="model-context-protocol-advanced-topics" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/322b89z3mttch/promo-image.1749756672.svg" aria-hidden="true" alt="image" /></div>
<p>Model Context Protocol: Advanced Topics</p>
<p>Discover advanced Model Context Protocol implementation patterns including sampling, notifications, file system access, and transport mechanisms for production MCP server development.</p>
</a><a href="https://anthropic.skilljar.com/claude-in-amazon-bedrock" title="Claude with Amazon Bedrock" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="8" data-oid="1rr2v7ii2ts1q" data-coid="3i2kpf9wzkzfs" data-course="claude-in-amazon-bedrock" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/3i2kpf9wzkzfs/promo-image.1749602244.svg" aria-hidden="true" alt="image" /></div>
<p>Claude with Amazon Bedrock</p>
<p>As part of an accreditation program created for AWS, Anthropic launched a first-of-its-kind training for AWS employees. Here's the full course so you can follow along.</p>
</a><a href="https://anthropic.skilljar.com/claude-with-google-vertex" title="Claude with Google Cloud's Vertex AI" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="9" data-oid="27qd2s5mmsnzm" data-coid="1k0qj1i9wgzt" data-course="claude-with-google-vertex" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/1k0qj1i9wgzt/promo-image.1749602236.svg" aria-hidden="true" alt="image" /></div>
<p>Claude with Google Cloud's Vertex AI</p>
<p>This comprehensive course covers the full spectrum of working with Anthropic models through Google Cloud's Vertex AI.</p>
</a><a href="https://anthropic.skilljar.com/teaching-ai-fluency" title="Teaching AI Fluency" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="10" data-oid="1z1ggntgogc6y" data-coid="zjx5xtwwhlir" data-course="teaching-ai-fluency" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/zjx5xtwwhlir/promo-image.1755713683.png" aria-hidden="true" alt="image" /></div>
<p>Teaching AI Fluency</p>
<p>This course empowers academic faculty, instructional designers, and others to teach and assess AI Fluency in instructor-led settings.</p>
</a><a href="https://anthropic.skilljar.com/ai-fluency-for-nonprofits" title="AI Fluency for nonprofits" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="11" data-oid="2qv34d09tdzk" data-coid="37f6rpi1f0h0" data-course="ai-fluency-for-nonprofits" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/37f6rpi1f0h0/promo-image.1764610752.png" aria-hidden="true" alt="image" /></div>
<p>AI Fluency for nonprofits</p>
<p>This course empowers nonprofit professionals to develop AI fluency in order to increase organizational impact and efficiency while staying true to their mission and values.</p>
</a><a href="https://anthropic.skilljar.com/introduction-to-agent-skills" title="Introduction to agent skills" class="coursebox-container course theme-color-border-hover theme-no-hover" data-type="-c" data-tags="" data-order="12" data-oid="lczzcndyyoct" data-coid="377fuwy2g2o8k" data-course="introduction-to-agent-skills" data-course-status="unregistered">
<div class="coursebox-image"><img src="https://cc.sj-cdn.net/instructor/4hdejjwplbrm-anthropic/courses/377fuwy2g2o8k/promo-image.1771548391.png" aria-hidden="true" alt="image" /></div>
<p>Introduction to agent skills</p>
<p>Learn how to build, configure, and share Skills in Claude Code — reusable markdown instructions that Claude automatically applies to the right tasks at the right time. This course takes you from creating your first Skill to distributing them across teams and troubleshooting common issues.</p>
</a></div><div id="catalog-stubs"><a href="" class="coursebox-container lesson theme-color-border-hover theme-no-hover" data-type="-l" data-tags="" data-oid="">
<p>Part of:</p>
</a><a href="" title="" class="search-only coursebox-container course theme-color-border-hover theme-no-hover" data-oid="" data-coid="" data-course="" data-course-status="" data-type="-c" data-tags="">
<div class="coursebox-image"><img src="" aria-hidden="true" alt="image" /></div>
</a><a href="" title="" class="coursebox-container course sj-course-series sj-path theme-color-border-hover theme-no-hover search-only" data-type="-x" data-tags="" data-order="" data-oid="" data-path-oid="" data-course-series="" data-path="" data-status="">
<div class="coursebox-image"><img src="" aria-hidden="true" alt="image" /></div>
</a></div></div></div>
    `;
  } else {
    return `
      <p>${
        screenshot.alt || "Screenshot"
      }</p>
    `;
  }
}
function generateModalCarousel() {
  return `
    
  `;
}
function initializeModalCarousel(courseData, enrollHref = '') {
  // Add modal to DOM if not already present
  if (!document.getElementById("clp__modal-overlay")) {
    document.body.insertAdjacentHTML("beforeend", generateModalCarousel());
  }
  const modal = document.getElementById("clp__modal-overlay");
  const modalImage = modal.querySelector(".clp__modal-image");
  const modalTitle = modal.querySelector(".clp__modal-title");
  const modalDescription = modal.querySelector(".clp__modal-description");
  const modalCounter = modal.querySelector(".clp__modal-counter");
  const modalEnrollBtn = modal.querySelector(".clp__modal-enroll-btn");
  const closeBtn = modal.querySelector(".clp__modal-close");
  const prevBtn = modal.querySelector(".clp__modal-prev");
  const nextBtn = modal.querySelector(".clp__modal-next");
  // Set the enroll button href
  if (modalEnrollBtn &amp;&amp; enrollHref) {
    modalEnrollBtn.href = enrollHref;
  }
  let currentSectionIndex = 0;
  let currentImageIndex = 0;
  let allSections = courseData.sections.filter(
    (section) =&gt; section.screenshots &amp;&amp; section.screenshots.length &gt; 0
  );
  function updateModal() {
    if (allSections.length === 0) return;
    const currentSection = allSections[currentSectionIndex];
    const currentImage = currentSection.screenshots[currentImageIndex];
    modalTitle.textContent = currentSection.title;
    modalDescription.textContent = currentSection.description;
    modalImage.src = currentImage.fullSizeUrl || currentImage.url;
    modalImage.alt = currentImage.alt || "Screenshot";
    // Update counter
    const totalImages = allSections.reduce(
      (sum, section) =&gt; sum + section.screenshots.length,
      0
    );
    let currentImageNumber = 1;
    for (let i = 0; i &lt; currentSectionIndex; i++) {
      currentImageNumber += allSections[i].screenshots.length;
    }
    currentImageNumber += currentImageIndex;
    modalCounter.textContent = `${currentImageNumber} of ${totalImages}`;
  }
  function nextImage() {
    const currentSection = allSections[currentSectionIndex];
    if (currentImageIndex &lt; currentSection.screenshots.length - 1) {
      currentImageIndex++;
    } else {
      // Move to next section
      if (currentSectionIndex &lt; allSections.length - 1) {
        currentSectionIndex++;
        currentImageIndex = 0;
      } else {
        // Wrap to first section
        currentSectionIndex = 0;
        currentImageIndex = 0;
      }
    }
    updateModal();
  }
  function prevImage() {
    if (currentImageIndex &gt; 0) {
      currentImageIndex--;
    } else {
      // Move to previous section
      if (currentSectionIndex &gt; 0) {
        currentSectionIndex--;
        currentImageIndex =
          allSections[currentSectionIndex].screenshots.length - 1;
      } else {
        // Wrap to last section
        currentSectionIndex = allSections.length - 1;
        currentImageIndex =
          allSections[currentSectionIndex].screenshots.length - 1;
      }
    }
    updateModal();
  }
  function openModal(sectionId, screenshotId) {
    // Find the section and image
    const sectionIndex = allSections.findIndex(
      (section) =&gt; section.id === sectionId
    );
    if (sectionIndex === -1) return;
    const section = allSections[sectionIndex];
    const imageIndex = section.screenshots.findIndex(
      (screenshot) =&gt; screenshot.id === screenshotId
    );
    if (imageIndex === -1) return;
    currentSectionIndex = sectionIndex;
    currentImageIndex = imageIndex;
    updateModal();
    modal.style.display = "flex";
    document.body.style.overflow = "hidden";
  }
  function closeModal() {
    modal.style.display = "none";
    document.body.style.overflow = "";
  }
  // Event listeners
  closeBtn.addEventListener("click", closeModal);
  nextBtn.addEventListener("click", nextImage);
  prevBtn.addEventListener("click", prevImage);
  // Click outside modal to close
  modal.addEventListener("click", (e) =&gt; {
    if (e.target === modal) {
      closeModal();
    }
  });
  // Keyboard navigation
  document.addEventListener("keydown", (e) =&gt; {
    if (modal.style.display === "flex") {
      switch (e.key) {
        case "Escape":
          closeModal();
          break;
        case "ArrowLeft":
          prevImage();
          break;
        case "ArrowRight":
          nextImage();
          break;
      }
    }
  });
  // Add click handlers to screenshot images
  document.addEventListener("click", (e) =&gt; {
    if (e.target.classList.contains("clp__screenshot-clickable")) {
      const sectionId = e.target.dataset.sectionId;
      const screenshotId = e.target.dataset.screenshotId;
      openModal(sectionId, screenshotId);
    }
  });
}
// Add to window for browser usage
if (typeof window !== "undefined") {
  window.renderScreenshot = renderScreenshot;
  window.generateModalCarousel = generateModalCarousel;
  window.initializeModalCarousel = initializeModalCarousel;
}
// Course Landing Page HTML Generator
function generateCourseLandingPage(courseData, videoElement, enrollHref) {
  const html = `
    <p>${generateHeroSection(courseData, videoElement, enrollHref)}
      ${generateMainContent(courseData)}</p>
  `;
  return html.trim();
}
function generateHeroSection(courseData, videoElement, enrollHref) {
  // Determine what to show for video
  let videoContent;
  if (videoElement) {
    // If we have an existing video element, use it directly
    videoContent = `<p>${videoElement.outerHTML}</p>`;
  } else {
    // Otherwise, show a fallback placeholder
    videoContent = `
      <div class="clp__video-container"><p>Course Overview</p></div>
    `;
  }
  var isPartnersDomain = window.location.hostname === "anthropic-partners.skilljar.com";
  var academyHref = isPartnersDomain ? "/" : "https://www.anthropic.com/learn";
  var coursesHref = isPartnersDomain ? "/" : "https://anthropic.skilljar.com/";
  return `
    <section class="clp__hero"><div class="clp__hero-content"><div class="clp__hero-text"><p><a href="https://anthropic.skilljar.com/$%7BacademyHref%7D" class="clp__breadcrumb-link">Anthropic Academy</a>
             / 
            <a href="https://anthropic.skilljar.com/$%7BcoursesHref%7D" class="clp__breadcrumb-link">Courses</a></p><p class="clp__subtitle">${courseData.subtitle}</p><p><a href="https://anthropic.skilljar.com/$%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20enrollHref%20%7C%7C" class="clp__enroll-btn">${courseData.enrollButtonText || "Enroll in Course"}</a>
            ${courseData.hideFreeTag ? "" : `FREE`}</p><p>Already registered? <a href="https://anthropic.skilljar.com/auth/login?next=$%7BencodeURIComponent(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20courseData.path%0A%20%20%20%20%20%20%20%20%20%20%20%20)%7D" class="clp__signin-link">Sign In</a></p>${courseData.hideShareButtons ? "" : ``}</div><p>${videoContent}
          ${courseData.stats ? generateStatsSection(courseData.stats) : ""}</p></div></section>
  `;
}
function generateStatsSection(stats) {
  return `
    <div class="clp__stats-container"><p>${stats.lectureCount}
        lectures</p><p>${stats.videoHours}
        ${
          stats.videoHours === 1 ? "hour" : "hours"
        } of video</p>${
        stats.quizCount &gt; 0
          ? `<p>${stats.quizCount}
        ${
          stats.quizCount &gt; 1 ? "quizzes" : "quiz"
        }</p>`
          : ""
      }<p>✓
        Certificate of completion</p></div>
  `;
}
function generateMainContent(courseData) {
  return `
    <p>${generateAboutThisCourse(courseData)}
    ${generateCourseSections(courseData.sections)}
    ${courseData.instructors ? generateInstructorsSection(courseData.instructors) : ''}
    ${courseData.extra ? generateExtraSection(courseData.extra) : ''}</p>
  `;
}
function generateCourseSections(sections) {
  if (!sections || sections.length === 0) return "";
  return `
    <section class="clp__sections-container"><h2 class="clp__section-title">Course sections</h2>${sections
        .map(
          (section) =&gt; `<div class="clp__section-block"><p class="clp__section-description">${section.description}</p>${
            section.screenshots &amp;&amp; section.screenshots.length &gt; 0
              ? `
            Course preview images<p>${section.screenshots
                .map((screenshot) =&gt; renderScreenshot(screenshot, section.id))
                .join("")}</p>`
              : ""
          }</div>`
        )
        .join("")}</section>
  `;
}
function generateInstructorsSection(instructors) {
  return `
    <section class="clp__instructors-container"><h2 class="clp__instructors-title">About the instructors</h2><div class="clp__instructors-card"><div class="clp__instructors-grid">${instructors
            .map(
              (instructor) =&gt; `<div class="clp__instructor-item"><img src="https://anthropic.skilljar.com/$%7Binstructor.avatar%7D" alt="${instructor.name}" class="clp__instructor-avatar" /></div>`
            )
            .join("")}</div></div></section>
  `;
}
function generateExtraSection(extra) {
  return `
    <section class="clp__extra-container">
  `;
}
function generateAboutThisCourse(courseData) {
  return `
    <div><div class="clp__course-details"><h2 class="clp__details-title">About this course</h2><p class="clp__details-text">${courseData.overview.description}</p>${courseData.overview.learningObjectives ? `<h3 class="clp__details-subtitle">Learning objectives</h3><p class="clp__details-text">By the end of this course, you'll be able to:</p><ul class="clp__details-list">
            
              
                  
              <li>${objective}</li>
            
              
              
          </ul>` : ''}
        ${courseData.overview.prerequisites ? `<h3 class="clp__details-subtitle">Prerequisites</h3><ul class="clp__details-list">
            
              
                  
              <li>${prereq}</li>
            
              
              
          </ul>` : ''}
        ${courseData.overview.targetAudience ? `<h3 class="clp__details-subtitle">Who this course is for</h3><p class="clp__details-text">${courseData.overview.targetAudience}</p>` : ''}</div></div>
  `;
}
// Share functions
function shareOnX(e) {
  e.preventDefault();
  const text =
    document.querySelector(".clp__title").textContent +
    " - " +
    document.querySelector(".clp__subtitle").textContent;
  const url = window.location.href;
  window.open(
    `https://twitter.com/intent/tweet?text=${encodeURIComponent(
      text
    )}&amp;url=${encodeURIComponent(url)}`,
    "_blank"
  );
}
function shareOnLinkedIn(e) {
  e.preventDefault();
  const url = window.location.href;
  window.open(
    `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(
      url
    )}`,
    "_blank"
  );
}
// Export the main function
if (typeof module !== "undefined" &amp;&amp; module.exports) {
  module.exports = { generateCourseLandingPage };
}
// Add to window for browser usage
if (typeof window !== "undefined") {
  window.generateCourseLandingPage = generateCourseLandingPage;
  window.shareOnX = shareOnX;
  window.shareOnLinkedIn = shareOnLinkedIn;
}
// Find the course data matching the current path
function getMatchingCourse() {
  const currentPath = window.location.pathname;
  const courses = Object.values(window._clpdata || {});
  return courses.find((course) =&gt; currentPath.includes(course.path));
}
// The AI Fluency series of courses hide the .lesson-top header
// on the lesson page, which is where the Chat with Claude
// button is usually located. If this is a AIF course then
// we will instead prepend the chatbutton to the course text content
function useAlternateLayout() {
  const course = getMatchingCourse();
  return course?.usesAlternateLayout || false;
}
function renderChatButton() {
  let chatButtonParent;
  if (useAlternateLayout()) {
    chatButtonParent = document.querySelector(".course-text-content");
  } else {
    chatButtonParent = document.querySelector(".lesson-top");
  }
  if (!chatButtonParent) {
    return null;
  }
  // Check if chat button already exists
  if (chatButtonParent.querySelector(".lp__chat-combo")) {
    console.warn("Chat button already exists, skipping");
    return null;
  }
  // Find matching course and get LLM content using its key
  const course = getMatchingCourse();
  const llmKey = course?.llmContentKey;
  const attachmentContent =
    llmKey &amp;&amp; window.__chatData ? window.__chatData[llmKey] : "";
  // Return early if no attachment content found
  if (!attachmentContent) {
    return null;
  }
  // Create combo button container
  const comboContainer = document.createElement("div");
  comboContainer.className = "lp__chat-combo";
  // Create main button
  const mainButton = document.createElement("button");
  mainButton.className = "lp__chat-button-main";
  mainButton.innerHTML = `
    <p>Anthropic
      Open in Claude</p>
  `;
  // Create dropdown button
  const dropdownButton = document.createElement("button");
  dropdownButton.className = "lp__chat-button-dropdown";
  dropdownButton.innerHTML = `
    
  `;
  // Create dropdown menu
  const dropdownMenu = document.createElement("div");
  dropdownMenu.className = "lp__chat-dropdown-menu";
  dropdownMenu.innerHTML = `
    <div class="lp__chat-dropdown-item" data-action="claude"><p>Anthropic</p><div class="lp__chat-text"><p>Open in Claude
          </p><p>Ask questions about this course</p></div></div>
    <div class="lp__chat-dropdown-item" data-action="copy"><div class="lp__chat-text"><p>Copy notes</p><p>Copy full course notes for LLMs</p></div></div>
  `;
  // Assemble combo button
  comboContainer.appendChild(mainButton);
  comboContainer.appendChild(dropdownButton);
  comboContainer.appendChild(dropdownMenu);
  // Add event listeners
  mainButton.onclick = () =&gt; openInClaude();
  dropdownButton.onclick = (e) =&gt; {
    e.stopPropagation();
    dropdownMenu.classList.toggle("lp__chat-dropdown-open");
    dropdownButton.classList.toggle("lp__dropdown-open");
  };
  // Add dropdown item listeners
  dropdownMenu.addEventListener("click", (e) =&gt; {
    const item = e.target.closest(".lp__chat-dropdown-item");
    if (!item) return;
    const action = item.dataset.action;
    if (action === "copy") {
      copyTranscript();
    } else if (action === "claude") {
      openInClaude();
    }
    dropdownMenu.classList.remove("lp__chat-dropdown-open");
    dropdownButton.classList.remove("lp__dropdown-open");
  });
  // Close dropdown when clicking outside
  document.addEventListener("click", (e) =&gt; {
    if (!comboContainer.contains(e.target)) {
      dropdownMenu.classList.remove("lp__chat-dropdown-open");
      dropdownButton.classList.remove("lp__dropdown-open");
    }
  });
  // Action functions
  function copyTranscript() {
    const mainButtonText = mainButton.querySelector("span");
    const dropdownItemText = dropdownMenu.querySelector(
      '[data-action="copy"] .lp__chat-title'
    );
    navigator.clipboard
      .writeText(attachmentContent)
      .then(() =&gt; {
        // Change text to "Copied!"
        mainButtonText.textContent = "Copied!";
        dropdownItemText.textContent = "Copied!";
        // Revert after 3 seconds
        setTimeout(() =&gt; {
          mainButtonText.textContent = "Open in Claude";
          dropdownItemText.textContent = "Copy notes";
        }, 3000);
      })
      .catch((err) =&gt; {
        console.error("Failed to copy transcript:", err);
      });
  }
  function openInClaude() {
    const q = encodeURIComponent("Explain this concept:");
    const attachment = encodeURIComponent(attachmentContent);
    const linkUrl = `https://claude.ai/remix#q=${q}&amp;attachment=${attachment}`;
    window.open(linkUrl, "_blank", "noopener,noreferrer");
  }
  if (useAlternateLayout()) {
    chatButtonParent.prepend(comboContainer);
  } else {
    chatButtonParent.appendChild(comboContainer);
  }
  return comboContainer;
}
const VIOLET = "#cbcadb";
const MINT = "#bcd1ca";
class ResourceLinks {
  images = {
    quill: {
      imgAlt:
        "Ornate quill pen resting on a detailed hand, positioned against a textured background",
      imgSrc:
        "https://www-cdn.anthropic.com/images/4zrzovbb/website/33dbe8f783d4835a838b4c4ae85d3c04e352fee1-1000x1000.svg",
    },
    head: {
      imgAlt:
        "Stylized hand and head silhouette with interconnected node and abstract geometric elements",
      imgSrc:
        "https://www-cdn.anthropic.com/images/4zrzovbb/website/46e4aa7ea208ed440d5bd9e9e3a0ee66bc336ff1-1000x1000.svg",
    },
  };
  resources = [
    // AI Fluency
    {
      title: "AI Fluency vocabulary guide",
      description:
        "A reference for key terms you'll encounter, written in plain language. No need to memorize; just refer to it when needed.",
      img: "quill",
      attachmentTitle: "AI Fluency vocabulary cheat sheet.pdf",
      color: VIOLET,
    },
    {
      title: "The AI Fluency Framework summary (8.5x11)",
      description:
        "Quick visual reference for the four core competencies (the “4Ds”) and key concepts. Can be printed as a reference poster.",
      img: "quill",
      attachmentTitle: "1.2 AI Fluency Summary One-Pager.pdf",
      color: VIOLET,
    },
    {
      title: "The AI Fluency Framework summary (16x9)",
      description:
        "Quick visual reference for the four core competencies (the “4Ds”) and key concepts. Can be used in delivering presentations.",
      img: "quill",
      attachmentTitle: "1.2 AI Fluency Summary 16x9.pdf",
      color: MINT,
    },
    {
      title: "Overview of Generative AI",
      description: "Quick reference guide for understanding generative AI.",
      img: "quill",
      attachmentTitle: "DD1 Handout_ Overview of Generative AI.pdf",
      color: VIOLET,
    },
    {
      title: "Delegation summary slide (8.5x11)",
      description:
        "A concise summary of the Delegation competency that you can print as a quick reference.",
      img: "quill",
      attachmentTitle: "1.3 Delegation Summary.pdf",
      color: VIOLET,
    },
    {
      title: "Delegation summary slide (16x9)",
      description:
        "A concise summary of the Delegation competency that you can use in delivering presentations.",
      img: "quill",
      attachmentTitle: "1.3 Delegation Summary 16x9.pdf",
      color: MINT,
    },
    {
      title: "Description summary slide (8.5x11)",
      description:
        "A concise summary of the Delegation competency that you can print as a quick reference.",
      img: "quill",
      attachmentTitle: "1.5 Description Summary.pdf",
      color: VIOLET,
    },
    {
      title: "Description summary slide (16x9)",
      description:
        "A concise summary of the Delegation competency that you can use in presentations.",
      img: "quill",
      attachmentTitle: "1.5 Description Summary 16x9.pdf",
      color: MINT,
    },
    {
      title: "6 techniques for effective prompt engineering",
      description:
        "See how vague prompts can be transformed into effective ones with these real-world examples.",
      img: "quill",
      attachmentTitle: "DD2 Handout_ 6 Effective Prompting Techniques.pdf",
      color: VIOLET,
    },
    {
      title: "Discernment summary slide (8.5x11)",
      description:
        "A concise summary of the Discernment competency that you can print as a quick reference poster.",
      img: "quill",
      attachmentTitle: "1.6 Discernment Summary.pdf",
      color: VIOLET,
    },
    {
      title: "Discernment summary slide (16x9)",
      description:
        "A concise summary of the Discernment competency that you can use in presentations.",
      img: "quill",
      attachmentTitle: "1.6 Discernment Summary 16x9.pdf",
      color: MINT,
    },
    {
      title: "Diligence summary slide (8.5x11)",
      description:
        "A concise summary of the Diligence competency that you can print as a quick reference.",
      img: "quill",
      attachmentTitle: "1.8 Diligence Summary.pdf",
      color: VIOLET,
    },
    {
      title: "Diligence summary slide (16x9)",
      description:
        "A concise summary of the Diligence competency that you can use in presentations.",
      img: "quill",
      attachmentTitle: "1.8 Diligence Summary 16x9.pdf",
      color: MINT,
    },
  ];
  init() {
    const anchors = document.querySelectorAll(
      "#details-pane-summary-content .sj-text-downloads + ul a"
    );
    const resourceCards = [];
    anchors.forEach((anchor) =&gt; {
      const span = anchor.querySelector("span");
      if (!span) return;
      const spanText = span.textContent.trim();
      const matchedResource = this.resources.find(
        (resource) =&gt; resource.attachmentTitle === spanText
      );
      if (matchedResource) {
        const href = anchor.href;
        const img = this.images[matchedResource.img];
        const resourceHtml = this.createResource({
          href,
          description: matchedResource.description,
          title: matchedResource.title,
          imgAlt: img.imgAlt,
          imgSrc: img.imgSrc,
          bgColor: matchedResource.color,
        });
        resourceCards.push(resourceHtml);
      }
    });
    if (resourceCards.length &gt; 0) {
      // Remove the original ul element
      const ul = document.querySelector(
        "#details-pane-summary-content .sj-text-downloads + ul"
      );
      if (ul) {
        ul.remove();
      }
      // Create new container and add resource cards
      const downloadsHeader = document.querySelector(".sj-text-downloads");
      if (downloadsHeader) {
        const resourceContainer = document.createElement("div");
        resourceContainer.className = "resource__container";
        resourceContainer.innerHTML = resourceCards.join("");
        // Insert as sibling after the downloads header
        downloadsHeader.parentNode.insertBefore(
          resourceContainer,
          downloadsHeader.nextSibling
        );
      }
    }
  }
  createResource({ href, description, title, imgAlt, imgSrc, bgColor }) {
    return `
<div class="resource__wrapper"><div class="resource__image"><img alt="${imgAlt}" width="1000" height="1000" data-nimg="1" src="https://anthropic.skilljar.com/$%7BimgSrc%7D" /></div><div class="resource__content"><div class="resource__text_wrapper"><p class="resource__text">${description}</p></div><a class="resource__link" href="https://anthropic.skilljar.com/$%7Bhref%7D" rel="noopener" target="_blank" aria-label="Download">
      Download
    </a></div></div>
`;
  }
}
renderChatButton();
const resourceLinks = new ResourceLinks();
resourceLinks.init();
// Check if current path matches a course with usesAlternateLayout flag
function shouldUseAlternateLayout() {
  const currentPath = window.location.pathname;
  const courses = Object.values(window._clpdata || {});
  return courses.some((course) =&gt; {
    if (!course.usesAlternateLayout) return false;
    const matchesPath = currentPath.includes(course.path);
    const matchesPreview =
      course.previewId &amp;&amp; currentPath.includes(`preview/${course.previewId}`);
    return matchesPath || matchesPreview;
  });
}
// Apply specific CSS based on course layout type
if (shouldUseAlternateLayout()) {
  const style = document.createElement("style");
  style.textContent = `
    #lp-wrapper #lp-content #details-pane.columns #details-pane-inner #details-pane-content #details-pane-summary-content {
      flex-direction: column !important;
    }
  `;
  document.head.appendChild(style);
} else {
  const style = document.createElement("style");
  style.textContent = `
    #lesson-body #lesson-main #lesson-main-inner .lesson-top {
      display: flex !important;
    }
  `;
  document.head.appendChild(style);
}
const song = document.querySelector("#song");
if (song) {
  song.addEventListener("click", () =&gt; {
    const songWrapper = document.querySelector("#song-wrapper");
    if (songWrapper) {
      const existingAudio = songWrapper.querySelector("audio");
      if (existingAudio) {
        existingAudio.play();
        return;
      }
      const audio = document.createElement("audio");
      audio.controls = true;
      audio.autoplay = false;
      audio.id = "karaoke-audio";
      audio.src = "https://ant-lm-sj-s3.s3.us-east-1.amazonaws.com/script.js";
      audio.style.marginTop = "16px";
      audio.style.width = "100%";
      audio.style.maxWidth = "400px";
      songWrapper.appendChild(audio);
      const lines = [
        {
          text: "Welcome to our alpha test, my friend.",
          start: 6738,
          end: 11257,
        },
        {
          text: "It's long, but you'll make it till the end.",
          start: 11257,
          end: 15559,
        },
        {
          text: "We need your feedback, oh, it's so divine.",
          start: 15559,
          end: 20498,
        },
        {
          text: "To make this certification really shine.",
          start: 20498,
          end: 27357,
        },
        {
          text: "Don't use Claude, don't use Google.",
          start: 27357,
          end: 30753,
        },
        {
          text: "Don't even ask your precious Poodle.",
          start: 30753,
          end: 33960,
        },
        {
          text: "We're watching you, but not really, though.",
          start: 33960,
          end: 36653,
        },
        {
          text: "Just pretend that we're in the know.",
          start: 36653,
          end: 38357,
        },
        { text: "No external help, it's the rule.", start: 38357, end: 40360 },
        {
          text: "The pacing, the difficulty, the clarity, too.",
          start: 40360,
          end: 43648,
        },
        {
          text: "We need to know if this exam's killing you.",
          start: 43648,
          end: 47057,
        },
        {
          text: "Take it by yourself, serious and stern.",
          start: 47057,
          end: 50359,
        },
        { text: "Give it a try, help us learn.", start: 50359, end: 53660 },
        {
          text: "Your manager won't see your score.",
          start: 53660,
          end: 56758,
        },
        {
          text: "We promise this, we swear what's more.",
          start: 56758,
          end: 59951,
        },
        { text: "Your results are anonymized.", start: 59951, end: 63348 },
        {
          text: "So don't feel stressed or victimized.",
          start: 63348,
          end: 66649,
        },
        {
          text: "There's no cheating now, be strong and true.",
          start: 66649,
          end: 70058,
        },
        {
          text: "Leave feedback when you're finally through.",
          start: 70058,
          end: 73360,
        },
        { text: "This alpha test is just for fun.", start: 73360, end: 78555 },
        { text: "And data collection, everyone.", start: 78555, end: 81749 },
        {
          text: "Remember, don't ask your dog for help.",
          start: 81749,
          end: 86660,
        },
      ];
      let lyricsDiv = null;
      let currentLineIndex = -1;
      let isInitialized = false;
      function initializeLyrics() {
        if (isInitialized) return;
        lyricsDiv = document.createElement("div");
        lyricsDiv.id = "karaoke-lyrics";
        document.body.appendChild(lyricsDiv);
        isInitialized = true;
      }
      function updateDisplay() {
        if (!lyricsDiv) return;
        const currentTime = audio.currentTime * 1000;
        // Find current line
        let newLineIndex = -1;
        for (let i = 0; i &lt; lines.length; i++) {
          if (currentTime &gt;= lines[i].start &amp;&amp; currentTime &lt;= lines[i].end) {
            newLineIndex = i;
            break;
          }
        }
        // Update display if line changed
        if (newLineIndex !== currentLineIndex) {
          currentLineIndex = newLineIndex;
          lyricsDiv.innerHTML = "";
          // Show 3 lines: previous, current, next
          const linesToShow = [
            currentLineIndex - 1,
            currentLineIndex,
            currentLineIndex + 1,
          ];
          linesToShow.forEach((idx) =&gt; {
            if (idx &gt;= 0 &amp;&amp; idx &lt; lines.length) {
              const lineDiv = document.createElement("div");
              lineDiv.textContent = lines[idx].text;
              lineDiv.dataset.index = idx;
              if (idx === currentLineIndex) {
                lineDiv.className = "karaoke-line karaoke-current";
              } else if (idx &lt; currentLineIndex) {
                lineDiv.className = "karaoke-line karaoke-past";
              } else {
                lineDiv.className = "karaoke-line karaoke-upcoming";
              }
              lyricsDiv.appendChild(lineDiv);
            }
          });
        }
      }
      audio.addEventListener("timeupdate", updateDisplay);
      // Hide lyrics when paused, show when playing
      audio.addEventListener("pause", () =&gt; {
        if (lyricsDiv) {
          lyricsDiv.classList.add("karaoke-hidden");
        }
      });
      audio.addEventListener("play", () =&gt; {
        // Initialize lyrics div on first play
        if (!isInitialized) {
          initializeLyrics();
        }
        if (lyricsDiv) {
          lyricsDiv.classList.remove("karaoke-hidden");
        }
      });
    }
  });
}
const coursePaths = Object.keys(window._clpdata || {});
function revealDefaultContent() {
  const el = document.querySelector("#skilljar-content");
  if (el) {
    el.classList.add("reveal");
  }
}
function applyEnhancedStyling() {
  const currentPath = window.location.pathname;
  const isExactMatch = coursePaths.some((title) =&gt; currentPath === title);
  if (!isExactMatch) {
    revealDefaultContent();
    return;
  }
  // True if we're on any course landing page, registered or not
  if (window.skilljarCourse) {
    // True if we have already registered for the course
    if (window.skilljarCourseProgress) {
      revealDefaultContent();
    } else {
      // Apply course landing page template
      applyCourseLandingPageTemplate(currentPath);
    }
  } else {
    revealDefaultContent();
  }
}
function applyCourseLandingPageTemplate(path) {
  // Get the course data for the current path
  const courseData = window._clpdata &amp;&amp; window._clpdata[path];
  if (!courseData) {
    console.error("No course data found for path:", path);
    revealDefaultContent();
    return;
  }
  // Find the main content container
  const mainContent = document.querySelector("#skilljar-content");
  if (mainContent) {
    // Extract the existing video player before replacing content
    const existingVideoWrapper = mainContent.querySelector(
      ".dp-promo-image-wrapper"
    );
    let videoElement = null;
    if (existingVideoWrapper) {
      // Clone the video element to preserve event listeners and state
      videoElement = existingVideoWrapper.cloneNode(true);
    }
    // Extract the enroll button href
    const enrollButton = document.querySelector("#purchase-button");
    let enrollHref = "";
    if (enrollButton &amp;&amp; enrollButton.href) {
      enrollHref = enrollButton.href;
    }
    // Generate the HTML with the video element and enroll href
    const html = window.generateCourseLandingPage(
      courseData,
      videoElement,
      enrollHref
    );
    // Replace the content
    mainContent.innerHTML = html;
    initializeModalCarousel(courseData, enrollHref);
    // Reveal the content
    const el = document.querySelector("#skilljar-content");
    if (el) {
      el.classList.add("reveal");
    }
  } else {
    console.error("Could not find main content container");
    revealDefaultContent();
  }
}
applyEnhancedStyling();
// EAP Certification Landing Page HTML Generator
const EAP_CDN = "https://d7juhi4i8fsw0.cloudfront.net/images/";
const EAP_VIDEO_ID = "-iEzrQ6em-U";
const EAP_EXAM_GUIDE_URL =
  "https://everpath-course-content.s3-accelerate.amazonaws.com/instructor%2F8lsy243ftffjjy1cx9lm3o2bw%2Fpublic%2F1773274827%2FClaude+Certified+Architect+%E2%80%93+Foundations+Certification+Exam+Guide.pdf";
const EAP_PARTNER_URL = "https://claude.com/partners";
const EAP_STATS = [
  {
    icon: "academic-cap-smal.webp",
    title: "Exclusive for Anthropic Partners",
    description:
      "A ~301 level exam for practitioners at partner companies with foundational knowledge who are ready to demonstrate deeper, applied expertise.",
  },
  {
    icon: "timer-small.webp",
    title: "120 min Proctored Exam",
    description:
      "Complete 60 multiple-choice questions end-to-end in a single session. No external resources or breaks.",
  },
  {
    icon: "cert-small.webp",
    title: "Your Score Report",
    description:
      "Results within 2 business days with detailed section breakdowns. Digital certificate recognized by companies using Claude.",
  },
  {
    icon: "cc-small.webp",
    title: "Free for Early Access",
    description:
      "Free for the first 5,000 partner company employees. General availability will be $99.",
  },
];
const EAP_COMPETENCIES = [
  {
    title: "Agentic Architecture &amp; Orchestration",
    weight: "27%",
    description:
      "Design agentic loops, orchestrate multi-agent systems with coordinator-subagent patterns, implement task decomposition, and manage session state and workflow enforcement.",
  },
  {
    title: "Tool Design &amp; MCP Integration",
    weight: "18%",
    description:
      "Design effective tool interfaces with clear boundaries, implement structured error responses, integrate MCP servers, and distribute tools appropriately across agents.",
  },
  {
    title: "Claude Code Configuration &amp; Workflows",
    weight: "20%",
    description:
      "Configure CLAUDE.md hierarchies, create custom slash commands, apply path-specific rules, know when to use plan mode, and integrate into CI/CD pipelines.",
  },
  {
    title: "Prompt Engineering &amp; Structured Output",
    weight: "20%",
    description:
      "Design prompts with explicit criteria, apply few-shot techniques, enforce structured output with JSON schemas, and implement validation and retry loops.",
  },
  {
    title: "Context Management &amp; Reliability",
    weight: "15%",
    description:
      "Preserve critical information across long interactions, design escalation patterns, manage error propagation in multi-agent systems, and handle uncertainty with confidence calibration.",
  },
];
const EAP_SCENARIOS = [
  {
    title: "Customer Support Resolution Agent",
    description:
      "You are building a customer support resolution agent using the Claude Agent SDK. The agent handles high-ambiguity requests like returns, billing disputes, and account issues. It has access to your backend systems through custom MCP tools (get_customer, lookup_order, process_refund, escalate_to_human). Your target is 80%+ first-contact resolution while knowing when to escalate.",
    domains: ["Agentic Architecture &amp; Orchestration", "Tool Design &amp; MCP Integration", "Context Management &amp; Reliability"],
  },
  {
    title: "Code Generation with Claude Code",
    description:
      "You are using Claude Code to accelerate software development. Your team uses it for code generation, refactoring, debugging, and documentation. You need to integrate it into your development workflow with custom slash commands, CLAUDE.md configurations, and understand when to use plan mode vs direct execution.",
    domains: ["Claude Code Configuration &amp; Workflows", "Context Management &amp; Reliability"],
  },
  {
    title: "Multi-Agent Research System",
    description:
      "You are building a multi-agent research system using the Claude Agent SDK. A coordinator agent delegates to specialized subagents: one searches the web, one analyzes documents, one synthesizes findings, and one generates reports. The system researches topics and produces comprehensive, cited reports.",
    domains: ["Agentic Architecture &amp; Orchestration", "Tool Design &amp; MCP Integration", "Context Management &amp; Reliability"],
  },
  {
    title: "Developer Productivity with Claude",
    description:
      "You are building developer productivity tools using the Claude Agent SDK. The agent helps engineers explore unfamiliar codebases, understand legacy systems, generate boilerplate code, and automate repetitive tasks. It uses the built-in tools (Read, Write, Bash, Grep, Glob) and integrates with MCP servers.",
    domains: ["Tool Design &amp; MCP Integration", "Claude Code Configuration &amp; Workflows", "Agentic Architecture &amp; Orchestration"],
  },
  {
    title: "Claude Code for Continuous Integration",
    description:
      "You are integrating Claude Code into your CI/CD pipeline. The system runs automated code reviews, generates test cases, and provides feedback on pull requests. You need to design prompts that provide actionable feedback and minimize false positives.",
    domains: ["Claude Code Configuration &amp; Workflows", "Prompt Engineering &amp; Structured Output"],
  },
  {
    title: "Structured Data Extraction",
    description:
      "You are building a structured data extraction system using Claude. The system extracts information from unstructured documents, validates the output using JSON schemas, and maintains high accuracy. It must handle edge cases gracefully and integrate with downstream systems.",
    domains: ["Prompt Engineering &amp; Structured Output", "Context Management &amp; Reliability"],
  },
];
const EAP_COURSES = [
  {
    color: "blue",
    icon: "hand-lightning.webp",
    title: "Building with the Claude API",
    href: "/claude-with-the-anthropic-api",
  },
  {
    color: "purple",
    icon: "atoms-on-page.webp",
    title: "Introduction to Model Context Protocol",
    href: "/introduction-to-model-context-protocol",
  },
  {
    color: "sage",
    icon: "browser.webp",
    title: "Claude Code in Action",
    href: "/claude-code-in-action",
  },
  {
    color: "pink",
    icon: "apple-book-learning.webp",
    title: "Claude 101",
    href: "/claude-101",
  },
];
const EAP_FAQS = [
  {
    q: "Who is this certification for?",
    a: "This certification is currently available to Anthropic partners. It's intended for a technical audience — a ~301 level exam designed for practitioners who have foundational knowledge and are ready to demonstrate deeper, applied expertise. If your organization isn't yet an Anthropic partner, you can <a href="https://anthropic.skilljar.com/%5C%22%22" target="\&quot;_blank\&quot;" rel="\&quot;noopener\&quot;">apply to become one</a>.",
  },
  {
    q: "What are the prerequisites?",
    a: "Completion of at least all 200-level courses in the course catalog, working familiarity with Agent SDK, and having built solutions with Claude Code, Agent SDK, Anthropic API, and MCP.",
  },
  {
    q: "How should I prepare?",
    a: "Get very familiar with the Exam Guide — it contains the scenarios that will appear on the exam, the domains and skill areas, and preparation exercises. Then take the Practice Exam and aim for a score greater than 900/1000.",
  },
  {
    q: "Will the exam be proctored?",
    a: "Yes, we've partnered with ProctorFree for exam proctoring.",
  },
  {
    q: "How many attempts are permitted?",
    a: "One attempt.",
  },
  {
    q: "Is there a cost?",
    a: "The exam is free for the first 5,000 partner company employees during Early Access. After that, general availability pricing will be $99.",
  },
  {
    q: "Do I get a badge if I pass?",
    a: "Yes! Practitioners who pass receive a CCA-F badge that is shareable on LinkedIn.",
  },
  {
    q: "Have a question not covered here?",
    a: 'Email Anthropic Education Support at <a href="mailto:academy-support@anthropic.com">academy-support@anthropic.com</a>.',
  },
];
function generateEapLandingPage(loginUrl, signupUrl, isPartners) {
  var registerUrl = signupUrl || loginUrl;
  var html = '<p>' +
    eapHero(registerUrl, isPartners) +
    eapStats() +
    eapCompetencies() +
    eapScenarios() +
    eapRecommended() +
    eapFaq() +
    eapCtaFooter(registerUrl) +
    '</p>';
  return html;
}
function eapHero(registerUrl, isPartners) {
  var partnerNote = isPartners ? '' :
    '<p class="eap__partner-note">' +
      'Not an Anthropic partner? ' +
      '<a href="https://anthropic.skilljar.com/'%20+%20EAP_PARTNER_URL%20+%20'" target="_blank" rel="noopener">Apply to become one →</a>' +
    '</p>';
  return '' +
    '<section class="eap__hero eap__section--ivory">' +
      '<div class="eap__hero-content">' +
        '<div class="eap__hero-text">' +
          '' +
          '<p class="eap__hero-subtitle">Prove your expertise in building production-grade applications with Claude.</p>' +
          '<p>' +
            '<a href="https://anthropic.skilljar.com/'%20+%20registerUrl%20+%20'" class="eap__btn">Register for the Exam</a>' +
            '<a href="https://anthropic.skilljar.com/'%20+%20EAP_EXAM_GUIDE_URL%20+%20'" class="eap__btn--outline" target="_blank" rel="noopener">' +
              'Download the exam guide' +
              '↓' +
            '</a>' +
          '</p>' +
          partnerNote +
        '</div>' +
        '<div class="eap__hero-right">' +
          '<p>' +
            '' +
          '</p>' +
        '</div>' +
      '</div>' +
    '</section>';
}
function eapStats() {
  var items = EAP_STATS.map(function (stat) {
    return '' +
      '';
  }).join('');
  return '' +
    '<section class="eap__stats eap__section--ivory">' +
      '<p>' + items + '</p>' +
    '</section>';
}
function eapCompetencies() {
  var rows = EAP_COMPETENCIES.map(function (comp) {
    return '' +
      '<div class="eap__competency-row">' +
        '●' +
        '<p>' +
          comp.title +
          '' + comp.weight + '' +
        '</p>' +
        '<p>' + comp.description + '</p>' +
      '</div>';
  }).join('');
  return '' +
    '<section class="eap__section eap__section--white">' +
      '<div class="eap__section-inner">' +
        '' +
        '<p>' + rows + '</p>' +
      '</div>' +
    '</section>';
}
function eapScenarios() {
  var cards = EAP_SCENARIOS.map(function (s, i) {
    var domains = s.domains.map(function (d) {
      return '' + d + '';
    }).join('');
    return '' +
      '<div class="eap__scenario-card">' +
        '<p>Scenario ' + (i + 1) + '</p>' +
        '<h3 class="eap__scenario-title">' + s.title + '</h3>' +
        '<p class="eap__scenario-description">' + s.description + '</p>' +
        '<p>' + domains + '</p>' +
      '</div>';
  }).join('');
  return '' +
    '<section class="eap__section eap__section--ivory">' +
      '<div class="eap__section-inner">' +
        '' +
        '<div class="eap__scenarios-carousel">' +
          '<p>' + cards + '</p>' +
        '</div>' +
        '<p>' +
          'Scroll to see more →' +
          '<a href="https://anthropic.skilljar.com/'%20+%20EAP_EXAM_GUIDE_URL%20+%20'" class="eap__btn--outline" target="_blank" rel="noopener">' +
            'Full scenarios in the Exam Guide' +
            '↓' +
          '</a>' +
        '</p>' +
      '</div>' +
    '</section>';
}
function eapRecommended() {
  var cards = EAP_COURSES.map(function (course) {
    return '' +
      '<a href="https://anthropic.skilljar.com/'%20+%20course.href%20+%20'" class="eap__course-card eap__course-card--' + course.color + '">' +
        '<div class="eap__course-card-top">' +
          '<img src="https://anthropic.skilljar.com/'%20+%20EAP_CDN%20+%20course.icon%20+%20'" alt="" class="eap__course-card-icon" />' +
        '</div>' +
        '' +
      '</a>';
  }).join('');
  return '' +
    '<section class="eap__section eap__section--white">' +
      '<div class="eap__section-inner">' +
        '' +
        '<p>' + cards + '</p>' +
      '</div>' +
    '</section>';
}
function eapFaq() {
  var items = EAP_FAQS.map(function (faq, i) {
    var id = 'eap-faq-' + i;
    return '' +
      '<div class="faq-container">' +
        '' +
        '' +
        '<label for="' + id + '" class="faq-label">' +
          '' + faq.q + '' +
          '' +
            '' +
              '' +
              '' +
            '' +
            '' +
              '' +
            '' +
          '' +
        '</label>' +
        '<article class="faq-content">' +
          '<div class="faq-post text-b2"><p>' + faq.a + '</p></div>' +
        '</article>' +
      '</div>';
  }).join('');
  return '' +
    '<section class="eap__section eap__section--ivory">' +
      '<div class="eap__section-inner">' +
        '<p>' +
          '</p><h2 class="eap__section-title">FAQ</h2>' +
        '' +
        '<p>' + items + '</p>' +
      '</div>' +
    '</section>';
}
function eapCtaFooter(registerUrl) {
  return '' +
    '';
}
if (typeof window !== "undefined") {
  window.generateEapLandingPage = generateEapLandingPage;
}
(function () {
  var EAP_PATH = "/claude-certified-architect-foundations-access-request";
  var currentPath = window.location.pathname.replace(/\/$/, "");
  if (currentPath !== EAP_PATH) return;
  function applyEapLandingPage() {
    // Only take over if Skilljar served a 404 (logged-out user).
    // If the user is logged in, Skilljar shows real content — leave it alone.
    if (!document.querySelector(".sj-page-error-404")) return;
    var mainContent = document.querySelector("#skilljar-content");
    if (!mainContent) return;
    var target = window.location.pathname;
    var loginUrl = "/auth/login?next=" + encodeURIComponent(target);
    var isPartners =
      window.location.hostname === "anthropic-partners.skilljar.com";
    var signupUrl;
    if (!isPartners) {
      signupUrl =
        "https://accounts.skilljar.com/accounts/signup/" +
        "?next=%2Fauth%2Fendpoint%2Flogin%2Fresult%3Fnext%3D" +
        encodeURIComponent(encodeURIComponent(target)) +
        "%26d%3Dcahl60vup5xv&amp;t=3gufixqhei80k&amp;d=cahl60vup5xv";
    }
    mainContent.innerHTML = window.generateEapLandingPage(
      loginUrl,
      signupUrl,
      isPartners
    );
    mainContent.classList.add("reveal");
    document.title = "Claude Certified Architect – Foundations | Anthropic Academy";
  }
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", applyEapLandingPage);
  } else {
    applyEapLandingPage();
  }
})();
// Inject this code into the Skilljar iframe page
// Dev preview message bridge. Ships to prod but the origin check makes it
// inert for real users — only localhost:3000 can trigger eval/style injection.
window.addEventListener("message", function (event) {
  if (event.origin !== "http://localhost:3000") {
    return;
  }
  if (event.data.type === "code") {
    eval(event.data.code);
  }
  if (event.data.type === "clpdata") {
    window._clpdata = event.data.data;
  }
  // Check if the message is for updating styles
  if (event.data.type === "updateStyles") {
    // Remove any previously injected styles
    const existingStyle = document.getElementById("parent-injected-styles");
    if (existingStyle) {
      existingStyle.remove();
    }
    // Create new style element
    const style = document.createElement("style");
    style.id = "parent-injected-styles";
    style.textContent = event.data.styles;
    // Append to document head
    document.head.appendChild(style);
  }
  if (event.data.type === "hideStyles") {
    setupStyleObserver();
  }
});
// STYLE ELEMENT OBSERVER
// Function to set up MutationObserver for style elements in head
function setupStyleObserver() {
  // Remove any existing PROD_STYLES elements
  document.head.querySelectorAll("style").forEach(function (style) {
    if (
      style.textContent.includes("PROD_STYLES") &amp;&amp;
      style.id !== "parent-injected-styles"
    ) {
      style.remove();
    }
  });
  const observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
      mutation.addedNodes.forEach(function (node) {
        if (
          node.nodeName === "STYLE" &amp;&amp;
          node.textContent.includes("PROD_STYLES") &amp;&amp;
          node.id !== "parent-injected-styles"
        ) {
          node.remove();
        }
      });
    });
  });
  // Start observing the head element for style additions
  observer.observe(document.head, {
    childList: true,
    subtree: false,
  });
}
// SKILLJAR REDIRECT AFTER LOGOUT
// FIXME: get skilljar to override their server side redirect settings
// 1. Hide the page immediately if we expect a redirect
(function () {
  // Check if we're coming from a logout on a lesson page
  const redirectUrl = sessionStorage.getItem("redirect_after_logout");
  if (redirectUrl) {
    // Add a style to hide the page content immediately
    const style = document.createElement("style");
    style.textContent = `
          body { 
              visibility: hidden !important; 
              opacity: 0 !important;
          }
      `;
    document.head.appendChild(style);
    // Check if user is logged out and redirect
    setTimeout(function () {
      if (typeof skilljarUser === "undefined") {
        sessionStorage.removeItem("redirect_after_logout");
        window.location.replace(redirectUrl);
      } else {
        // User is still logged in, show the page
        document.body.style.visibility = "visible";
        document.body.style.opacity = "1";
        sessionStorage.removeItem("redirect_after_logout");
      }
    }, 50); // Very short delay to check login status
  }
})();
// 2. Intercept logout clicks on lesson pages
document.addEventListener("click", function (event) {
  // Current URL pattern for lesson pages
  const currentUrl = window.location.href;
  const lessonPattern =
    /^(https:\/\/anthropic-poc\.skilljar\.com\/[^\/]+)\/\d+$/;
  const isLessonPage = lessonPattern.test(currentUrl);
  if (!isLessonPage) return;
  // Check for logout button
  const logoutButton = event.target.closest(
    'a[href*="/logout"], a[href*="/sign-out"], .logout-button, .sign-out'
  );
  if (logoutButton) {
    event.preventDefault();
    // Extract course URL
    const match = currentUrl.match(lessonPattern);
    if (match) {
      const courseUrl = match[1];
      sessionStorage.setItem("redirect_after_logout", courseUrl);
      // Add loading state to current page
      document.body.style.opacity = "0.5";
      document.body.insertAdjacentHTML(
        "beforeend",
        `
              <p>Signing out...</p>
          `
      );
    }
    // Proceed with logout
    window.location.href = logoutButton.href;
  }
});
// HIDE SIGN-IN LINKS FOR LOGGED-IN USERS
(function () {
  if (typeof skilljarUser !== "undefined") {
    document.querySelectorAll(".signin, .clp__signin-text").forEach(function (el) {
      el.style.display = "none";
    });
  }
})();
// REWRITE ANTHROPIC ACADEMY LINKS FOR LOGGED-IN PARTNERS USERS
(function () {
  if (typeof skilljarUser === "undefined") return;
  if (window.self === window.top &amp;&amp; window.location.hostname !== "anthropic-test.skilljar.com") return;
  var targetHref = "https://anthropic-partners.skilljar.com";
  function rewriteAcademyLinks(root) {
    (root || document).querySelectorAll('a[href*="anthropic.com/learn"]').forEach(function (link) {
      link.href = targetHref;
    });
  }
  rewriteAcademyLinks();
  // Watch for dynamically added links (e.g., course landing page content)
  new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
      mutation.addedNodes.forEach(function (node) {
        if (node.nodeType !== Node.ELEMENT_NODE) return;
        if (node.tagName === "A" &amp;&amp; node.href &amp;&amp; node.href.includes("anthropic.com/learn")) {
          node.href = targetHref;
        }
        if (node.querySelectorAll) {
          rewriteAcademyLinks(node);
        }
      });
    });
  }).observe(document.body, {
    childList: true,
    subtree: true,
  });
})();
// VIDEO PLAYBACK RATE
// Video playback rate persistence script
(function () {
  "use strict";
  const STORAGE_KEY = "video-playback-rate";
  // Function to save playback rate to session storage
  function savePlaybackRate(rate) {
    try {
      sessionStorage.setItem(STORAGE_KEY, rate.toString());
    } catch (e) {
      console.error("Failed to save playback rate:", e);
    }
  }
  // Function to get saved playback rate from session storage
  function getSavedPlaybackRate() {
    try {
      const saved = sessionStorage.getItem(STORAGE_KEY);
      return saved ? parseFloat(saved) : null;
    } catch (e) {
      console.error("Failed to retrieve playback rate:", e);
      return null;
    }
  }
  // Function to setup video player
  function setupVideoPlayer(video) {
    // Skip if already setup
    if (video.dataset.playbackRateSetup) return;
    video.dataset.playbackRateSetup = "true";
    // Listen for rate changes
    video.addEventListener("ratechange", function () {
      savePlaybackRate(video.playbackRate);
    });
    // Listen for play event to restore saved rate
    video.addEventListener(
      "play",
      function () {
        const savedRate = getSavedPlaybackRate();
        if (savedRate &amp;&amp; savedRate !== video.playbackRate) {
          video.playbackRate = savedRate;
        }
      },
      { once: true }
    ); // Only set rate on first play
    // Also set rate if video is already playing
    if (!video.paused) {
      const savedRate = getSavedPlaybackRate();
      if (savedRate &amp;&amp; savedRate !== video.playbackRate) {
        video.playbackRate = savedRate;
      }
    }
  }
  // Function to find and setup all video players
  function findAndSetupVideos() {
    const videos = document.querySelectorAll("video");
    videos.forEach(setupVideoPlayer);
  }
  // Setup when DOM is ready
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", findAndSetupVideos);
  } else {
    findAndSetupVideos();
  }
  // Watch for dynamically added videos
  const observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
      mutation.addedNodes.forEach(function (node) {
        if (node.nodeName === "VIDEO") {
          setupVideoPlayer(node);
        } else if (node.querySelectorAll) {
          const videos = node.querySelectorAll("video");
          videos.forEach(setupVideoPlayer);
        }
      });
    });
  });
  // Start observing
  observer.observe(document.body, {
    childList: true,
    subtree: true,
  });
})();
// FA-CHECK ICON DISPLAY FIX
// Function to change fa-check icons from display:block to display:inline
function fixFaCheckIcons() {
  const faCheckIcons = document.querySelectorAll(
    'i.fa.fa-check[aria-hidden="true"]'
  );
  faCheckIcons.forEach(function (icon) {
    // Check if the icon has display: block style
    const computedStyle = window.getComputedStyle(icon);
    const inlineStyle = icon.style.display;
    // Check both computed style and inline style for display: block
    if (computedStyle.display === "block" || inlineStyle === "block") {
      icon.style.display = "inline";
    }
  });
}
// Run the fix when DOM is ready
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", fixFaCheckIcons);
} else {
  fixFaCheckIcons();
}
// Also watch for dynamically added fa-check icons
const faCheckObserver = new MutationObserver(function (mutations) {
  mutations.forEach(function (mutation) {
    mutation.addedNodes.forEach(function (node) {
      if (node.nodeType === Node.ELEMENT_NODE) {
        // Check if the added node is a fa-check icon
        if (node.matches &amp;&amp; node.matches('i.fa.fa-check[aria-hidden="true"]')) {
          if (
            window.getComputedStyle(node).display === "block" ||
            node.style.display === "block"
          ) {
            node.style.display = "inline";
          }
        }
        // Check for fa-check icons within the added node
        if (node.querySelectorAll) {
          const icons = node.querySelectorAll(
            'i.fa.fa-check[aria-hidden="true"]'
          );
          icons.forEach(function (icon) {
            if (
              window.getComputedStyle(icon).display === "block" ||
              icon.style.display === "block"
            ) {
              icon.style.display = "inline";
            }
          });
        }
      }
    });
  });
});
// Start observing for fa-check icons
faCheckObserver.observe(document.body, {
  childList: true,
  subtree: true,
});
// CHECKOUT PAYMENT PAGE LAYOUT FIX
// Fix layout issue on checkout payment page by changing column width from large-7 to large-6
// This addresses a visual layout problem where the payment form column is too wide
function fixCheckoutPaymentLayout() {
  // Only run on checkout payment pages
  if (!window.location.pathname.includes('/checkout/') ||
      !window.location.pathname.includes('/payment')) {
    return;
  }
  const targetDiv = document.querySelector('.large-7.columns');
  if (targetDiv &amp;&amp; targetDiv.classList.contains('large-7')) {
    targetDiv.classList.replace('large-7', 'large-6');
  }
}
// Run the fix when DOM is ready
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", fixCheckoutPaymentLayout);
} else {
  fixCheckoutPaymentLayout();
}
// Watch for dynamically added content (in case the element loads after initial page load)
if (window.location.pathname.includes('/checkout/') &amp;&amp;
    window.location.pathname.includes('/payment')) {
  const checkoutObserver = new MutationObserver(function (mutations) {
    const targetDiv = document.querySelector('.large-7.columns');
    if (targetDiv &amp;&amp; targetDiv.classList.contains('large-7')) {
      fixCheckoutPaymentLayout();
      checkoutObserver.disconnect(); // Stop observing once we've made the fix
    }
  });
  checkoutObserver.observe(document.body, {
    childList: true,
    subtree: true,
  });
}
// CUSTOMIZE 404 PAGE FOR CERTIFICATION/EXAM PATHS
// When logged-out users hit certification exam pages they get a 404; show a
// login-required message instead of the generic "page not found" text.
(function () {
  var certificationPaths = [
    "/claude-certified-architect-foundations-certification",
    "/anthropic-certification-practice-exam",
  ];
  var currentPath = window.location.pathname.replace(/\/$/, "");
  if (certificationPaths.indexOf(currentPath) === -1) return;
  function customize404() {
    if (!document.querySelector(".sj-page-error-404")) return;
    var titleSpan = document.querySelector(".sj-text-page-not-found span");
    if (titleSpan) {
      titleSpan.textContent = "Login Required";
    }
    var explanationSpan = document.querySelector(
      ".sj-text-page-not-found-explanation span"
    );
    if (!explanationSpan) return;
    var target =
      window.location.pathname + "?pc=ant-cca-f-eap-participants-02-24-2026";
    var loginUrl = "/auth/login?next=" + encodeURIComponent(target);
    var isPartners =
      window.location.hostname === "anthropic-partners.skilljar.com";
    if (isPartners) {
      explanationSpan.innerHTML =
        "This page is only available to registered users at partner companies. " +
        'Please <a href="https://anthropic.skilljar.com/'%20+%0A%20%20%20%20%20%20%20%20loginUrl%20+%0A%20%20%20%20%20%20%20%20'">log in</a> with your partner email to continue.';
    } else {
      // anthropic.skilljar.com uses accounts.skilljar.com for signup with
      // domain (d) and theme (t) identifiers baked into the redirect chain.
      var signupUrl =
        "https://accounts.skilljar.com/accounts/signup/" +
        "?next=%2Fauth%2Fendpoint%2Flogin%2Fresult%3Fnext%3D" +
        encodeURIComponent(encodeURIComponent(target)) +
        "%26d%3Dcahl60vup5xv&amp;t=3gufixqhei80k&amp;d=cahl60vup5xv";
      explanationSpan.innerHTML =
        "This page is only available to registered users. " +
        'Please <a href="https://anthropic.skilljar.com/'%20+%0A%20%20%20%20%20%20%20%20loginUrl%20+%0A%20%20%20%20%20%20%20%20'">log in</a> with your company email, ' +
        'or <a href="https://anthropic.skilljar.com/'%20+%0A%20%20%20%20%20%20%20%20signupUrl%20+%0A%20%20%20%20%20%20%20%20'">sign up</a> if you don’t already have an account.';
    }
  }
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", customize404);
  } else {
    customize404();
  }
})();
window.parent.postMessage(
  {
    type: "injectReady",
  },
  "*"
);
})();
]]&gt;
</section>]]></description>
      <link>https://anthropic.skilljar.com/</link>
      <guid>https://anthropic.skilljar.com/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Notes on Writing Wasm]]></title>
      <description><![CDATA[<p>I’ve been writing an increasing amount of <a href="https://notes.brooklynzelenka.com/Notes/Rust" class="internal" data-slug="Notes/Rust">Rust</a>‑based <a href="https://notes.brooklynzelenka.com/Wasm" class="internal" data-slug="Wasm">Wasm</a> over the past few years. The internet has many opinions about Wasm, and <a href="https://notes.brooklynzelenka.com/Notes/wasm-bindgen" class="internal" data-slug="Notes/wasm-bindgen">wasm-bindgen</a> is — let’s say — not universally beloved, but as I get more experience with it and learn how to work around its shortcomings, I’ve found some patterns that have dramatically improved my relationship with it.</p><p>I want to be clear up front about two things:</p><ol><li>I deeply appreciate the work of the <a href="https://notes.brooklynzelenka.com/Notes/wasm-bindgen" class="internal" data-slug="Notes/wasm-bindgen">wasm-bindgen</a> maintainers.</li>
<li>It’s entirely possible that there are better ways to work with bindgen than presented here; this is just what’s worked for me in practice!</li>
</ol><p>I’ve seen excellent programmers really fight with bindgen. I don’t claim to have all the answers, but this post documents a set of patterns that have made Rust+Wasm dramatically less painful for me.</p><p>Unless you have a good reason not to:</p><ol><li>Pass everything over the Wasm boundary by <code>&amp;reference</code></li>
<li>Prefer <code>Rc&lt;RefCell&lt;T&gt;&gt;</code> or <code>Arc&lt;Mutex&lt;T&gt;&gt;</code><sup><a href="#user-content-fn-futures-mutex" id="user-content-fnref-futures-mutex" data-footnote-ref="" aria-describedby="footnote-label" class="internal alias">1</a></sup> over <code>&amp;mut</code></li>
<li>Do not derive <code>Copy</code> on exported types</li>
<li>Use <code>wasm_refgen</code> for any type that needs to cross the boundary in a collection (<code>Vec</code>, etc)</li>
<li>Prefix all Rust-exported types with <code>Wasm*</code> and set the <code>js_name</code>/<code>js_class</code> to the unprefixed name</li>
<li>Prefix all JS-imported types with <code>Js*</code></li>
<li>Implement <code>From&lt;YourError&gt; for JsValue</code> using <a href="https://docs.rs/js-sys/latest/js_sys/struct.Error.html" class="external"><code>js_sys::Error</code></a> for all of Rust-exported error types</li>
</ol><p>Some of these may seem strange without further explanation. Below give more of the rationale in detail.</p><p><code><a href="https://notes.brooklynzelenka.com/Notes/wasm-bindgen" class="internal" data-slug="Notes/wasm-bindgen">wasm-bindgen</a></code> generates glue code that lets Rust structs, methods, and functions be called from JS/TS. Some Rust types have direct JS representations (those implementing <a href="https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html" class="external"><code>IntoWasmAbi</code></a>); others live entirely on the Wasm side and are accessed through opaque handles.</p><p>Wasm bindings often look something like this:</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">#[wasm_bindgen(js_name = Foo)]
pub struct WasmFoo(RustFoo)
#[wasm_bindgen(js_name = Bar)]
pub struct WasmBar(RustBar)</pre></figure><p>Conceptually, JS holds tiny objects that look like <code>{ __wbg_ptr: 12345 }</code>, which index into a table on the Wasm side that owns the real Rust values.</p><p>The tricky part is that you’re juggling two memory models at once:</p><ul><li><a href="https://notes.brooklynzelenka.com/JavaScript" class="internal" data-slug="JavaScript">JavaScript</a>: garbage‑collected, re‑entrant, async</li>
<li><a href="https://notes.brooklynzelenka.com/Notes/Rust" class="internal" data-slug="Notes/Rust">Rust</a>: explicit ownership, borrowing, aliasing rules</li>
</ul><p>Bindgen tries to help, but it both under‑ and over‑fits: some safe patterns are rejected, and some straight-up footguns are happily accepted. Ultimately, everything that crosses the boundary must have some JS representation, so it pays to be cognisant about what that representation is.</p><pre class="mermaid" data-clipboard="&quot;flowchart TD\n subgraph JavaScript\n subgraph Foo\n jsFoo[\&quot;{ __wbg_ptr: 42817 }\&quot;]\n end\n\n subgraph Bar\n jsBar[\&quot;{ __wbg_ptr: 71902 }\&quot;]\n end\n end\n\n subgraph Wasm\n subgraph table[Boundary Table]\n objID1((42817)) --&gt; WasmFoo\n\n subgraph WasmFoo\n arc1[RustFoo]\n end\n\n objID2((71902)) --&gt; WasmBar\n subgraph WasmBar\n arc2[RustBar]\n end\n end\n end\n\n jsFoo -.-&gt; objID1\n jsBar -.-&gt; objID2&quot;">flowchart TD
    subgraph JavaScript
        subgraph Foo
            jsFoo["{ __wbg_ptr: 42817 }"]
        end
        subgraph Bar
            jsBar["{ __wbg_ptr: 71902 }"]
        end
    end
    subgraph Wasm
        subgraph table[Boundary Table]
            objID1((42817)) --&gt; WasmFoo
            subgraph WasmFoo
                arc1[RustFoo]
            end
            objID2((71902)) --&gt; WasmBar
            subgraph WasmBar
                arc2[RustBar]
            end
        end
    end
    jsFoo -.-&gt; objID1
    jsBar -.-&gt; objID2
</pre><h2 id="should-you-write-manual-bindings">Should You Write Manual Bindings?<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#should-you-write-manual-bindings" class="internal"></a></h2><p>My take on most things is “you do you”, and this one is very much a matter of taste. I see a fair amount of code online that seems to prefer manual conversions with <code>js_sys</code>. This is a reasonable strategy, but I have found it to be time consuming and brittle. If you change your Rust types, the compiler isn’t going to help you when you’re manually calling <code>dyn_into</code> to do runtime checks. Bindgen is going to insert the same runtime checks either way, but if you lean into its glue (including with some of the patterns presented here), you can get much better compile-time feedback.</p><p>It’s an old joke that the two hardest problems in computer science are naming, caching, and off-by-one-errors. Naming is extremely important for mental framing and keeping track of what’s happening, both of which can be a big source of pain when working with bindgen. As a rule, I use the current naming conventions:</p><blockquote class="callout quote" data-callout="quote">
<div class="callout-content"><p>Trait <code>IntoWasmAbi</code> […] A trait for anything that can be converted into a type that can cross the Wasm ABI directly.<br />— <a href="https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html" class="external">Source</a></p></div>
</blockquote><p>These are the primitive types of Wasm, such as <code>u32</code>, <code>String</code>, <code>Vec&lt;u8&gt;</code>, and so on. They get converted to/from native JS and Rust types when they cross the boundary. We do not need to do anything to these types.</p><h2 id="rust-exported-structs-get-wasm">Rust-Exported Structs Get <code>Wasm*</code><a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#rust-exported-structs-get-wasm" class="internal"></a></h2><p>This is where you’ll usually spend most of your time. Wrapping Rust enums and structs in newtypes to re-expose them to JS is the bread and butter of Wasm. These wrappers get prefixed with <code>Wasm*</code> to help distinguish them from JS-imported interfaces, <a href="https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html" class="external"><code>IntoWasmAbi</code></a> types, and plain Rust objects. On the JS-side we can strip the <code>Wasm</code>, since it will only get the one representation, and (if done correctly) the JS side generally doesn’t need to distinguish where a type comes from.</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum StreetLight {
    Red,
    Yellow,
    Gree,
}
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
#[wasm_bindgen(js_name = StreetLight)]
pub struct WasmStreetLight(StreetLight)
#[wasm_bindgen(js_class = StreetLight)]
impl WasmStreetLight {
    #[wasm_bindgen(constructor)]
    pub fn new() -&gt; Self {
        Self(StreetLight::Red)
    }
    // ...
}</pre></figure><p>On the JS side, there’s only one StreetLight, so the prefix disappears. On the Rust side, the prefix keeps exported types visually distinct from:</p><ul><li>Plain Rust types</li>
<li>JS‑imported interfaces</li>
<li><a href="https://docs.rs/wasm-bindgen/latest/wasm_bindgen/convert/trait.IntoWasmAbi.html" class="external"><code>IntoWasmAbi</code></a> values</li>
</ul><h2 id="js-imported-interfaces-get-js">JS-Imported Interfaces Get <code>Js*</code><a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#js-imported-interfaces-get-js" class="internal"></a></h2><p>Any interface brought into Rust via <code>extern "C"</code> get a <a href="https://en.wikipedia.org/wiki/Duck_typing" class="external">duck typed</a> interface (by default). These pass over the boundary without restriction, which makes them a very helpful escape hatch ___.</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_name = logCurrentTime)]
    pub fn js_log_current_time(timestamp: u32);
}
#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_name = Hero)]
    type JsCharacter;
    #[wasm_bindgen(method, getter, js_name = hp)]
    pub fn js_hp(this: &amp;JsCharacter) -&gt; u32;
}
// Elsewhere
const gonna_win: bool = maelle.js_hp() != 0</pre></figure><p>Duck typing is really helpful for cases where you want to expose a Rust trait to JS: as long as your Rust-exported type implements the interface, you can accept your Rust-exported type a JS-imported type, while retaining the ability to replace it with JS-imported types. A concrete example is if you’re exporting a storage interface, you likely have a default Rust implementation, but want extensibility if downstream devs want to give it an IndexedDB or S3 backend.</p><blockquote class="callout note" data-callout="note">
<div class="callout-content"><p>We’re going to abuse this “duck typed JS-imports on a Rust-export” later for <code><a href="https://notes.brooklynzelenka.com/Notes/wasm_refgen" class="internal" data-slug="Notes/wasm_refgen">wasm_refgen</a></code>.</p></div>
</blockquote><p>The main gotchas with this approach are that 1. it’s brittle if the interface changes, and 2. if you don’t prefix your methods on the Rust-side with <code>js_*</code>, you can run into namespace collisions (hence why I recommend prefixing these everywhere by convention). As an added bonus, this makes you <em>very</em> aware of where you’re making method calls over the Wasm boundary.</p><p><code>Copy</code> makes it trivially easy to accidentally duplicate a Rust value that is actually a thin handle to a resource, resulting in null pointers. Just make a habit of avoiding it on exported wrappers. This can be a hard muscle memory to break since we usually <em>want</em> <code>Copy</code> wherever possible in normal Rust code.</p><p><code>Copy</code> is only acceptable when exporting wrapping around pure data that has <code>IntoWasmAbi</code>, never for handles. I chalk this up as an optimisation; default to non-<code>Copy</code> unless you’re <em>really</em> sure it’s okay.</p><p>Try as it might, <code>wasm-bindgen</code> is unable to prevent handles breaking at runtime. A common culprit is passing an owned value to Rust:</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">#[wasm_bindgen(js_class = Foo)]
impl WasmFoo {
    #[wasm_bindgen(js_name = "doSomething")]
    pub fn do_something(&amp;self, bar: Bar) -&gt; Result&lt;(), Error&gt; {
        // ...
    }
    #[wasm_bindgen(js_name = "doSomethingElse")]
    pub fn do_something_else(&amp;self, bars: Vec&lt;Bar&gt;) -&gt; Result&lt;(), Error&gt; {
        // ...
    }
}</pre></figure><p>If you do the above, it will of course consume your <code>Bar</code>(s), but since this goes over the boundary you get no help from the compiler about how you manage the JS side! The object will get freed on the Rust side, but you still have a JS handle that now points to nothing. You might say something like “so much for memory safety”, and you wouldn’t be wrong.</p><p>Why would you find yourself in this situation? There’s a couple reasons:</p><ul><li>Bindgen forbids <code>&amp;[T]</code> unless <code>T: IntoWasmAbi</code></li>
<li><code>Vec&lt;&amp;T&gt;</code> is not allowed</li>
<li>You just want the compiler to stop yelling</li>
</ul><p>Types that have are <code>IntoWasmAbi</code> that are not <code>Copy</code> get cloned over the boundary (no handle) so they behave differently from both non-<code>IntoWasmAbi</code> and <code>Copy</code> types</p><h2 id="prefer-passing-by-refence-by-default">Prefer Passing By Refence (by Default)<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#prefer-passing-by-refence-by-default" class="internal"></a></h2><p>If you take one thing from this post, take this:</p><p>This one if pretty straightforward: pass everything around by reference. Consuming a value is totally “legal” to the compiler since it will happily free the memory on Rust side, <em>but the JS-side handle will not get cleaned up</em>. The next time you go to use that handle, it will <code>throw</code> an error. Unless you’re doing something specific with memory management, just outright avoid this situation: pass by <code>&amp;reference</code> and use interior mutability.</p><p>This is a pretty easy pattern to follow: default to wrapping non-<code>IntoWasmAbi</code> types in <code>Rc&lt;RefCell&lt;T&gt;&gt;</code> or <code>Arc&lt;Mutex&lt;T&gt;&gt;</code><sup><a href="#user-content-fn-futures-mutex" id="user-content-fnref-futures-mutex-2" data-footnote-ref="" aria-describedby="footnote-label" class="internal alias">1</a></sup> depending on if and how you have your code structured for async. The cost of going over the Wasm boundary definitely eclipses an <code>Rc</code> bump, so this is highly unlikely to be a performance bottleneck.</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">#[derive(Debug, Clone)]
#[wasm_bindgen(js_name = Foo)]
pub struct WasmFoo(pub(crate) Rc&lt;RefCell&lt;Foo&gt;&gt;)
#[derive(Debug, Clone)]
#[wasm_bindgen(js_name = Bar)]
pub struct WasmBar(pub(crate) Rc&lt;RefCell&lt;Bar&gt;&gt;)
#[wasm_bindgen(js_class = Foo)]
impl WasmFoo {
    #[wasm_bindgen(js_name = "doSomething")]
    pub fn do_something(&amp;self, bar: WasmBar) -&gt; Result&lt;(), Error&gt; {
        // ...
    }
}</pre></figure><h2 id="avoid-mut">Avoid <code>&amp;mut</code><a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#avoid-mut" class="internal"></a></h2><p>This one can be pretty frustrating when it happens: there are cases where taking <code>&amp;mut self</code> can throw runtime errors due to re-entrancy. This pops up more frequently than I would have expected given that the default behaviour of JS is single threaded, but JS’s <code>async</code> doesn’t have to respect Rust’s compile-time exclusivity<sup><a href="#user-content-fn-mut-vs-excl" id="user-content-fnref-mut-vs-excl" data-footnote-ref="" aria-describedby="footnote-label" class="internal alias">2</a></sup> checks.</p><p>As mentioned earlier, you can use <code>extern "C"</code> JS-imports to model any duck typed interface, <em>including</em> Rust-exports. This means that we are able to work around several restrictions<sup><a href="#user-content-fn-lot-in-life" id="user-content-fnref-lot-in-life" data-footnote-ref="" aria-describedby="footnote-label" class="internal alias">3</a></sup> in <code><a href="https://notes.brooklynzelenka.com/Notes/wasm-bindgen" class="internal" data-slug="Notes/wasm-bindgen">wasm-bindgen</a></code>.</p><h2 id="owned-collection-restriction">Owned Collection Restriction<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#owned-collection-restriction" class="internal"></a></h2><p>Bindgen restricts which types can be passed across the boundary. The one folks often run into first is that <code>&amp;[T]</code> only works when <code>T</code> is <code>IntoWasmAbi</code> (including JS-imported types<sup><a href="#user-content-fn-too-much-nuance" id="user-content-fnref-too-much-nuance" data-footnote-ref="" aria-describedby="footnote-label" class="internal alias">4</a></sup>) — i.e. usually not your Rust-exported structs. This means that you are often forced to construct a <code>Vec&lt;T&gt;</code>. This makes sense since JS is going to take control over the resulting JS array, and can mutate it as it pleases. It also means that when the type comes back in, you are unable to accept it as <code>&amp;[T]</code> or <code>Vec&lt;T&gt;</code> unless the earlier <code>IntoWasmAbi</code> caveat applies.</p><p>A classic example of this is returning an owned <code>Vec&lt;T&gt;</code> of instead of a slice when <code>T</code> does not implement a JS-managed type. What’s returned to JS are not a bunch of <code>T</code>s, but rather <em>handles</em> (e.g. <code>{ __wbg_ptr: 12345 }</code>) to <code>T</code>s that live on the Wasm side.<sup><a href="#user-content-fn-too-much-nuance" id="user-content-fnref-too-much-nuance-2" data-footnote-ref="" aria-describedby="footnote-label" class="internal alias">4</a></sup></p><p>On the other hand, <em>we’re</em> able to treat handles as duck typed objects that conform to some interface. Handles are far less restricted than Rust-exported types, and can be passed around more freely.</p><p>The workaround is fairly straightforward:</p><ul><li>Make your exported type cheap to clone</li>
<li>Expose a namespaced clone method</li>
<li>Import that method via a JS interface</li>
<li>Convert with friendly ergonomics (<code>.into</code>)</li>
</ul><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">// Step 1: make it inexpensive to `clone` (i.e. using `Rc` or `Arc` if not already cheap)
#[derive(Debug, Clone)]
#[wasm_bindgen(js_name = Character)]
pub struct WasmCharacter(Rc&lt;RefCell&lt;Character&gt;&gt;)
#[wasm_bindgen(js_class = Character)]
impl WasmCharacter {
    // ...
    // Step 2: expose a *namespaced* (important!) `clone` function on the Wasm export
    #[doc(hidden)]
    pub fn __myapp_character_clone(&amp;self) -&gt; Self {
        self.clone()
    }
}
#[wasm_bindgen]
extern "C" {
    type JsCharacter
    // Step 3: create a JS-imported interface with that namespaced `clone`
    pub fn __myapp_character_clone(this: &amp;JsCharacter) -&gt; WasmCharacter;
}
// Step 4: for convenience, wrap the namespaced clone in a `.from`
impl From&lt;JsChcaracter&gt; for WasmCharacter {
    fn from(js: JsCharacter) -&gt; Self {
        js.__myapp_character_clone()
    }
}
//                             Nicely typed Vec
// Step 5: use it!                 vvvvv
pub fn do_many_things(js_foos: Vec&lt;JsFoo&gt;) {
  let rust_foos: Vec&lt;WasmFoo&gt; = js_foos.iter().map(Into::into).collect();
  // ...             ^^^^^^^
  //                Converted
}</pre></figure><p>This still requires that you to manually track which parts bindgen thinks are JS-imports and which it thinks are Rust-exports, but with our <a href="#names-matter" class="internal alias">naming convention</a> it’s pretty clear what’s happening. The conversion isn’t <em>free</em>, but (IMO) it makes your interfaces significantly more flexible and legible.</p><h3 id="use-wasm_refgen">Use <a href="https://notes.brooklynzelenka.com/Notes/wasm_refgen" class="internal" data-slug="Notes/wasm_refgen">wasm_refgen</a><a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#use-wasm_refgen" class="internal"></a></h3><p>The above pattern can be a bit brittle — even while writing the boilerplate — since all of the names have to line up <em>just so</em>, and you don’t get compiler help when crossing the boundary like this. To help make this more solid, I’ve wrapped this pattern up as a macro exported from <code><a href="https://notes.brooklynzelenka.com/Notes/wasm_refgen" class="internal" data-slug="Notes/wasm_refgen">wasm_refgen</a></code>.</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">use std::{rc::Rc, cell::RefCell};
use wasm_bindgen::prelude::*;
use wasm_refgen::wasm_refgen;
#[derive(Clone)]
#[wasm_bindgen(js_name = "Foo")]
pub struct WasmFoo {
   map: Rc&lt;RefCell&lt;HashMap&lt;String, u8&gt;&gt;&gt;, // Cheap to clone
   id: u32 // Cheap to clone
}
#[wasm_refgen(js_ref = JsFoo)] // &lt;-- THIS
#[wasm_bindgen(js_class = "Foo")]
impl WasmFoo {
   // ... your normal methods
}</pre></figure><p>Here’s a diagram from the README about how it works:</p><figure data-rehype-pretty-code-figure=""><pre data-language="text" data-theme="one-light dracula" class="c7">                   ┌───────────────────────────┐
                   │                           │
                   │      JS Foo instance      │
                   │        Class: Foo         │
                   │ Object { wbg_ptr: 12345 } │
                   │                           │
                   └─┬──────────────────────┬──┘
                     │                      │
                     │                      │
                Implements                  │
                     │                      │
                     │                      │
         ┌───────────▼───────────────┐      │
         │                           │      │
         │     TS Interface: Foo     │  Pointer
         │       only method:        │      │
         │   __wasm_refgen_to_Foo    │      │
         │                           │      │
         └───────────┬───────────────┘      │
JS/TS                │                      │
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ 
 Wasm                │                      │
                     │                      │
         ┌───────────┼──────────────────────┼───────────┐
         │           ▼                      ▼           │
         │ ┌────────────────┐        ┌────────────────┐ │
         │ │                │        │                │ │
         │ │     &amp;JsFoo     ◀────────▶    WasmFoo     │ │
         │ │ Opaque Wrapper │        │  Instance #1   │ │
         │ │                │        │                │ │
         │ └────────────────┘        └────────────────┘ │
         └──────────────────────┬───────────────────────┘
                                │
                                │
                          Into::into
                 (uses `__wasm_refgen_to_Foo`) 
               (which is a wrapper for `clone`)
                                │
                                │
                                ▼
                       ┌────────────────┐
                       │                │
                       │    WasmFoo     │
                       │  Instance #2   │
                       │                │
                       └────────────────┘</pre></figure><p>References passed over the boundary are already passed by ownership by bindgen — but these handles grab the reference off the boundary table. Recall that our <code>Into::into</code> calls <code>clone</code> under the hood, so these are always safe to consume without breaking the JS handle!</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">pub fn do_many_things(js_foos: Vec&lt;JsFoo&gt;) {
  let rust_foos: Vec&lt;WasmFoo&gt; = js_foos.iter().map(Into::into).collect();
  // ...
}</pre></figure><p>There are a few ways to handle errors coming from Wasm, but IMO the best balance of detail and convenience is to turn them into <code>js_sys::Error</code>s on their way to <code>JsValue</code>. This lets us return <code>Result&lt;T, MyError&gt;</code> instead of <code>Result&lt;T, JsValue&gt;</code>.</p><p>For example, let’s say we have this type:</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">#[derive(Debug, Clone, thiserror::Error)]
pub enum RwError {
    #[error("cannot read {0}")]
    CannotRead(String),
    #[error("cannot write")]
    CannotWrite
}</pre></figure><p>The fact that this is an enum is actually not a problem (the rest of the technique would work), but if you’re wrapping a different crate you’ll need a newtype wrapper:</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">// Important: no #[wasm_bindgen]
#[derive(Debug, Clone, thiserror::Error)]
#[error(transparent)]
pub struct WasmRwError(#[from] RwError) // #[from] gets us `?` notation to lift into the newtype</pre></figure><p>We “could” slap a <code>#[wasm_bindgen]</code> on this and call it a day, but then we wouldn’t get nice error info on the JS side. Instead, we convert to <code>JsValue</code> ourselves with this final bit of glue:</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">impl From&lt;WasmRwError&gt; for JsValue {
    fn from(wasm: WasmRwError) -&gt; Self {
        let err = js_sys::Error::new(&amp;wasm.to_string()); // Error message
        err.set_name("RwError"); // Nice JS error type
        err.into() // Convert to `JsValue`
    }
}</pre></figure><p>Now you can return <code>Result&lt;T, WasmRwError&gt;</code>, including if you want to call the Wasm-wrapped function elsewhere in your code. It retains the nice error on the Rust side (at minimum types-as-documentation). You also get <code>?</code> notation without needing to do in-place <code>JsValue</code> conversion everywhere this error occurs; bindgen will helpfully do the conversion for you.</p><ul><li>Typed Rust errors</li>
<li><code>?</code> propagation</li>
<li>Real JS <code>Error</code> objects</li>
<li>Zero boilerplate at call sites</li>
</ul><p>This works as a copy-paste template; I’ve considered wrapping it as a macro but it’s less than 10 LOC. I was actually surprised that something like <code>#[wasm_bindgen(error)]</code> wasn’t available (maybe it is and I just can’t find it; heck maybe it’s worth contributing upstream).</p><p>This is a quality of life improvement that has saved me many hours of grief: print the exact build version, dirty status, and Git hash to the <code>console</code> on startup. If you’re working on your Wasm project at the same time as developing a pure-JS library that consumes it, getting a JS bundler like <code><a href="https://notes.brooklynzelenka.com/Vite" class="internal" data-slug="Vite">Vite</a></code> to pick up changes can be flaky at best.</p><p>This takes a bit of setup, especially if you’re in a Cargo workspace, but pays off. Here’s my current setup:</p><figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="toml" data-theme="one-light dracula">$WORKSPACE/Cargo.toml</figcaption><pre data-language="toml" data-theme="one-light dracula" class="c7">[workspace]
resolver = "3"
members = [
  "build_info",
  # ...
]</pre></figure><figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="toml" data-theme="one-light dracula">$WORKSPACE/build_info/Cargo.toml</figcaption><pre data-language="toml" data-theme="one-light dracula" class="c7">[package]
name = "build_info"
publish = false
# ...</pre></figure><figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="rust" data-theme="one-light dracula">$WORKSPACE/build_info/build.rs</figcaption><pre data-language="rust" data-theme="one-light dracula" class="c7">use std::{
    env, fs,
    path::{Path, PathBuf},
    process::Command,
    time::{SystemTime, UNIX_EPOCH},
};
#[allow(clippy::unwrap_used)]
fn main() {
    let ws = env::var("CARGO_WORKSPACE_DIR").map_or_else(
        |_| PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
        PathBuf::from,
    );
    let repo_root = find_repo_root(&amp;ws).unwrap_or(ws.clone());
    let git_dir = repo_root.join(".git");
    watch_git(&amp;git_dir);
    let git_hash = cmd_out(
        "git",
        &amp;[
            "-C",
            #[allow(clippy::unwrap_used)]
            repo_root.to_str().unwrap(),
            "rev-parse",
            "--short",
            "HEAD",
        ],
    )
    .unwrap_or_else(|| "unknown".to_string());
    let dirty = cmd_out(
        "git",
        &amp;["-C", repo_root.to_str().unwrap(), "status", "--porcelain"],
    )
    .is_some_and(|s| !s.is_empty());
    let git_hash = if dirty {
        let secs = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        format!("{git_hash}-dirty-{secs}")
    } else {
        git_hash
    };
    println!("cargo:rustc-env=GIT_HASH={git_hash}");
}
fn cmd_out(cmd: &amp;str, args: &amp;[&amp;str]) -&gt; Option&lt;String&gt; {
    Command::new(cmd).args(args).output().ok().and_then(|o| {
        if o.status.success() {
            Some(String::from_utf8_lossy(&amp;o.stdout).trim().to_string())
        } else {
            None
        }
    })
}
fn find_repo_root(start: &amp;Path) -&gt; Option&lt;PathBuf&gt; {
    let mut cur = Some(start);
    while let Some(dir) = cur {
        if dir.join(".git").exists() {
            return Some(dir.to_path_buf());
        }
        cur = dir.parent();
    }
    None
}
fn watch_git(git_dir: &amp;Path) {
    println!("cargo:rerun-if-changed={}", git_dir.join("HEAD").display());
    if let Ok(head) = fs::read_to_string(git_dir.join("HEAD")) {
        if let Some(rest) = head.strip_prefix("ref: ").map(str::trim) {
            println!("cargo:rerun-if-changed={}", git_dir.join(rest).display());
            println!(
                "cargo:rerun-if-changed={}",
                git_dir.join("packed-refs").display()
            );
        }
    }
    println!("cargo:rerun-if-changed={}", git_dir.join("index").display());
    let fetch_head = git_dir.join("FETCH_HEAD");
    if fetch_head.exists() {
        println!("cargo:rerun-if-changed={}", fetch_head.display());
    }
}</pre></figure><figure data-rehype-pretty-code-figure=""><figcaption data-rehype-pretty-code-title="" data-language="rust" data-theme="one-light dracula">$WORKSPACE/build_info/src/lib.rs</figcaption><pre data-language="rust" data-theme="one-light dracula" class="c7">#![no_std]
pub const GIT_HASH: &amp;str = env!("GIT_HASH");</pre></figure><p>…and finally where to get it to print in Wasm:</p><figure data-rehype-pretty-code-figure=""><pre data-language="rust" data-theme="one-light dracula" class="c7">use wasm_bindgen::prelude::*;
// ...
#[wasm_bindgen(start)]
pub fn start() {
    set_panic_hook();
    // I actually use `tracing::info!` here,
    // but that's out of scope for this article
    web_sys::console.info1(format!(
        "️your_package_wasm v{} ({})",
        env!("CARGO_PKG_VERSION"),
        build_info::GIT_HASH
    ));
}</pre></figure><p>Rust+Wasm is powerful—but unforgiving if you pretend the boundary isn’t there. Be explicit, name things clearly, pass by reference, and duck typing around any (unreasonable) limitations bindgen places on you.</p><p>With any luck, that’s helpful to others! I may update this over time as I find myself using more patterns.</p><section data-footnotes="" class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes<a role="anchor" aria-hidden="true" tabindex="-1" data-no-popover="true" href="#footnote-label" class="internal"></a></h2><ol><li id="user-content-fn-futures-mutex">
<p>FWIW I prefer <a href="https://docs.rs/futures/latest/futures/lock/struct.Mutex.html" class="external"><code>futures::lock::Mutex</code></a> on <code>std</code>, or <a href="https://docs.rs/async-lock/3.4.1/async_lock/struct.Mutex.html" class="external"><code>async_lock::Mutex</code></a> under <code>no_std</code>. <a href="#user-content-fnref-futures-mutex" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref internal alias">↩</a> <a href="#user-content-fnref-futures-mutex-2" data-footnote-backref="" aria-label="Back to reference 1-2" class="data-footnote-backref internal">↩<sup>2</sup></a></p>
</li>
<li id="user-content-fn-mut-vs-excl">
<p>I’m actually more annoyed by Rust on this one (see earlier comment about naming being important). <code>&amp;mut</code> isn’t “just” a mutable reference; it’s an <em>exclusive</em> reference, which happens to make direct mutability viable, but the semantics are more about exclusivity. <a href="#user-content-fnref-mut-vs-excl" data-footnote-backref="" aria-label="Back to reference 2" class="data-footnote-backref internal alias">↩</a></p>
</li>
<li id="user-content-fn-lot-in-life">
<p>I sometimes wonder if it’s my lot in life to import features between langauges. <a href="https://notes.brooklynzelenka.com/Notes/Witchcraft-(Elixir-Library)" class="internal alias" data-slug="Notes/Witchcraft-(Elixir-Library)">Witchcraft</a> was my first real library of note, and I can’t seem to stop abusing languages this way  <a href="#user-content-fnref-lot-in-life" data-footnote-backref="" aria-label="Back to reference 3" class="data-footnote-backref internal alias">↩</a></p>
</li>
<li id="user-content-fn-too-much-nuance">
<p>This simple example is already more nuance than would be ideal to juggle when writing code. <a href="#user-content-fnref-too-much-nuance" data-footnote-backref="" aria-label="Back to reference 4" class="data-footnote-backref internal alias">↩</a> <a href="#user-content-fnref-too-much-nuance-2" data-footnote-backref="" aria-label="Back to reference 4-2" class="data-footnote-backref internal">↩<sup>2</sup></a></p>
</li>
</ol></section>]]></description>
      <link>https://notes.brooklynzelenka.com/Blog/Notes-on-Writing-Wasm</link>
      <guid>https://notes.brooklynzelenka.com/Blog/Notes-on-Writing-Wasm</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Filesystems are having a moment]]></title>
      <description><![CDATA[<div class="text-left mx-auto mb-6"><p class="text-gray-500">published: February 24, 2026</p><hr class="w-1/3 mt-2" /></div><p> - A collection of sprouting thoughts.</p><img src="https://madalitso.me/images/file.png" alt="image" /><p>I used to work at a vector database company. My entire job was helping people understand why they needed a database purpose-built for AI; embeddings, semantic search, the whole thing. So it's a little funny that I'm writing this. But here I am, watching everyone in the AI ecosystem suddenly rediscover the humble filesystem, and I think they might be onto something bigger than most people realize.</p><p>Not bigger than databases. Different from databases. I need to say that upfront because I already know someone is going to read this and think I'm saying "files good, databases bad." I'm not. Stay with me.</p><p>If you've been paying any attention to the AI agent space over the last few months, you've noticed something strange. <a href="https://www.llamaindex.ai/blog/files-are-all-you-need" rel="nofollow noopener noreferrer" target="_blank">LlamaIndex</a> published "Files Are All You Need." <a href="https://blog.langchain.com/how-agents-can-use-filesystems-for-context-engineering/" rel="nofollow noopener noreferrer" target="_blank">LangChain</a> wrote about how agents can use filesystems for context engineering. <a href="https://blogs.oracle.com/developers/comparing-file-systems-and-databases-for-effective-ai-agent-memory-management" rel="nofollow noopener noreferrer" target="_blank">Oracle</a>, <em>yes Oracle (who is cooking btw)</em>, put out a piece comparing filesystems and databases for agent memory. <a href="https://overreacted.io/a-social-filesystem/" rel="nofollow noopener noreferrer" target="_blank">Dan Abramov</a> wrote about a social filesystem built on the AT Protocol. <a href="https://archil.com/post/why-file-systems-are-here-to-stay" rel="nofollow noopener noreferrer" target="_blank">Archil</a> is building cloud volumes specifically because agents want POSIX file systems.</p><p>Jerry Liu from LlamaIndex put it bluntly: instead of one agent with hundreds of tools, we're moving toward a world where the agent has access to a filesystem and maybe 5-10 tools. That's it. Filesystem, code interpreter, web access. And that's as general, if not more general than an agent with 100+ MCP tools.</p><p><a href="https://karpathy.bearblog.dev/year-in-review-2025/" rel="nofollow noopener noreferrer" target="_blank">Karpathy</a> made the adjacent observation that stuck with me. He pointed out that Claude Code works because it runs on your computer, with your environment, your data, your context. It's not a website you go to — it's a little <em>spirit</em> that lives on your machine. OpenAI got this wrong, he argued, by focusing on cloud deployments in containers orchestrated from ChatGPT instead of simply running on localhost.</p><p>And here's the thing that makes all of this matter commercially: coding agents make up the majority of actual AI use cases right now. Anthropic is reportedly approaching profitability, and a huge chunk of that is driven by Claude Code, a CLI tool. Not a chatbot. A tool that reads and writes files on your filesystem.</p><img src="https://madalitso.me/images/window.png" alt="image" /><h4 id="context-windows-arent-memory">Context windows aren't memory</h4><p>Here's where I think most of the discourse misses the deeper point.</p><p>Memory; in the human, psychological sense is fundamental to how we function. We don't re-read our entire life story every time we make a decision. We have long-term storage, selective recall, the ability to forget things that don't matter and surface things that do. Context windows in LLMs are none of that. They're more like a whiteboard that someone keeps erasing.</p><p>If you've used Claude Code for any real project, you know the dread of watching that "context left until auto-compact" notification creep closer. Your entire conversation, all the context the agent has built up about your codebase, your preferences, your decisions about to be compressed or lost.</p><p>Filesystems solve this in the most boring, obvious way possible. Write things down. Put them in files. Read them back when you need them. Claude's <code>CLAUDE.md</code> file gives the agent persistent context about your project. Cursor stores past chat history as searchable files. People are writing <code>aboutme.md</code> files that act as portable identity descriptors any agent can read i.e. your preferences, your skills, your working style, all in a file that moves between applications without anyone needing to coordinate an API.</p><p>Except! It might not be quite that simple.</p><p>A <a href="https://arxiv.org/abs/2602.11988" rel="nofollow noopener noreferrer" target="_blank">recent paper from ETH Zürich</a> evaluated whether these repository-level context files actually help coding agents complete tasks. The finding was counterintuitive: across multiple agents and models, context files tended to <em>reduce</em> task success rates while increasing inference cost by over 20%. Agents given context files explored more broadly, ran more tests, traversed more files — but all that thoroughness delayed them from actually reaching the code that needed fixing. The files acted like a checklist that agents took too seriously.</p><p>This sounds like it undermines the whole premise. But I think it actually sharpens it. The paper's conclusion wasn't "don't use context files." It was that <strong>unnecessary requirements make tasks harder, and context files should describe only minimal requirements.</strong> The problem isn't the filesystem as a persistence layer. The problem is people treating <code>CLAUDE.md</code> like a 2,000-word onboarding document instead of a concise set of constraints. Which brings us to the question of standards.</p><img src="https://madalitso.me/images/web.png" alt="image" /><h4 id="the-file-format-is-the-api-but-which-file">The file format is the API (but which file?)</h4><p>Right now we have <code>CLAUDE.md</code>, <code>AGENTS.md</code>, <code>copilot-instructions.md</code>, <code>.cursorrules</code>, and probably five more by the time you read this. Everyone agrees that agents need persistent filesystem-based context. Nobody agrees on what the file should be called or what should go in it. I see efforts to consolidate, this is good.</p><p>Dan Abramov's piece on a <a href="https://overreacted.io/a-social-filesystem/" rel="nofollow noopener noreferrer" target="_blank">social filesystem</a> crystallized something important here. He describes how the AT Protocol treats user data as files in a personal repository; structured, owned by the user, readable by any app that speaks the format. The critical design choice is that different apps don't need to agree on what a "post" is. They just need to namespace their formats (using domain names, like Java packages) so they don't collide. Apps are reactive to files. Every app's database becomes derived data i.e. a cached materialized view of everybody's folders.</p><p>The same tension exists in the agent context file space. We don't need <code>CLAUDE.md</code> and <code>AGENTS.md</code> and <code>copilot-instructions.md</code> to converge into one file. We need them to coexist without collision. And to be fair, some convergence is happening. Anthropic released <a href="https://agentskills.io" rel="nofollow noopener noreferrer" target="_blank">Agent Skills</a> as an open standard, a <code>SKILL.md</code> format that Microsoft, OpenAI, Atlassian, GitHub, and Cursor have all adopted. A skill you write for Claude Code works in Codex, works in Copilot. The file format <em>is</em> the API.</p><p><a href="https://github.com/qwibitai/nanoclaw" rel="nofollow noopener noreferrer" target="_blank">NanoClaw</a>, a lightweight personal AI assistant framework, takes this to its logical conclusion. Instead of building an ever-expanding feature set, it uses a "skills over features" model. Want Telegram support? There's no Telegram module. There's a <code>/add-telegram</code> skill, essentially a markdown file that teaches Claude Code how to rewrite your installation to add the integration. Skills are just files. They're portable, auditable, and composable. No MCP server required. No plugin marketplace to browse. Just a folder with a <code>SKILL.md</code> in it.</p><p>This is interoperability without coordination. And I want to be specific about what I mean by that, because it's a strong claim. In tech, getting two competing products to work together usually requires either a formal standard that takes years to ratify, or a dominant platform that forces compatibility. Files sidestep both. If two apps can read markdown, they can share context. If they both understand the SKILL.md format, they can share capabilities. Nobody had to sign a partnership agreement. Nobody had to attend a standards body meeting. The file format does the coordinating.</p><h4 id="the-bottleneck-shifted">The bottleneck shifted</h4><p>There's a useful analogy from infrastructure. Traditional data architectures were designed around the assumption that storage was the bottleneck. The CPU waited for data from memory or disk, and computation was essentially reactive to whatever storage made available. But as processing power outpaced storage I/O, the <a href="https://www.moonfire.com/stories/the-lakehouse-era/" rel="nofollow noopener noreferrer" target="_blank">paradigm shifted</a>. The industry moved toward <a href="https://www.pracdata.io/p/zero-disk-architecture-the-future?hide_intro_popup=true" rel="nofollow noopener noreferrer" target="_blank">decoupling storage and compute</a>, letting each scale independently, which is how we ended up with architectures like S3 plus ephemeral compute clusters. The bottleneck moved, and everything reorganized around the new constraint.</p><p>Something similar is happening with AI agents. The bottleneck isn't model capability or compute. It's context. Models are smart enough. They're just forgetful. And filesystems, for all their simplicity, are an incredibly effective way to manage persistent context at the exact point where the agent runs — on the developer's machine, in their environment, with their data already there.</p><h4 id="youre-using-a-graph-and-you-dont-know-it">You're using a graph and you don't know it</h4><p>Now, I'd be a <em>frawd</em> if I didn't acknowledge the tension here. <a href="https://x.com/nayshins/status/2009366290692231328" rel="nofollow noopener noreferrer" target="_blank">Someone on Twitter</a> joked that "all of you saying you don't need a graph for agents while using the filesystem are just in denial about using a graph." And... they're not wrong. A filesystem <em>is</em> a tree structure. Directories, subdirectories, files i.e. a directed acyclic graph. When your agent runs <code>ls</code>, <code>grep</code>, reads a file, follows a reference to another file, it's traversing a graph.</p><p>Richmond in Oracle's piece made the sharpest distinction I've seen: <strong>filesystems are winning as an interface, databases are winning as a substrate.</strong> The moment you want concurrent access, semantic search at scale, deduplication, recency weighting — you end up building your own indexes. Which is, let's be honest, basically a database.</p><p>Having worked at Weaviate, I can tell you that this isn't an either/or situation. The file interface is powerful because it's universal and LLMs already understand it. The database substrate is powerful because it provides the guarantees you need when things get real. The interesting future isn't files <em>versus</em> databases. It's files as the interface humans and agents interact with, backed by whatever substrate makes sense for the use case.</p><img src="https://madalitso.me/images/finger.png" alt="image" /><p>Here's my actual take on all of this, the thing I think people are dancing around but not saying directly.</p><p>Filesystems can redefine what personal computing means in the age of AI.</p><p>Not in the "everything runs locally" sense (but maybe?). In the sense that your data, your context, your preferences, your skills, your memory — lives in a format you own, that any agent can read, that isn't locked inside a specific application. Your <code>aboutme.md</code> works with your flavour of OpenClaw/NanoClaw today and whatever comes tomorrow. Your skills files are portable. Your project context persists across tools.</p><p>This is what personal computing was supposed to be before everything moved into walled-garden SaaS apps and proprietary databases. Files are the original open protocol. And now that AI agents are becoming the primary interface to computing, files are becoming the interoperability layer that makes it possible to switch tools, compose workflows, and maintain continuity across applications, all without anyone's permission.</p><p>I'll admit this is a bit idealistic. The history of open formats is littered with standards that won on paper and lost in practice. Companies have strong incentives to make their context files just different enough that switching costs remain high. The fact that we already have <code>CLAUDE.md</code> and <code>AGENTS.md</code> and <code>.cursorrules</code> coexisting rather than one universal format, is evidence that fragmentation is the default, not the exception. And the ETH Zürich paper is a reminder that even when the format exists, writing good context files is harder than it sounds. Most people will write bad ones, and bad context files are apparently worse than none at all.</p><p>But I keep coming back to something Dan Abramov wrote: our memories, our thoughts, our designs <em>should</em> outlive the software we used to create them. That's not a technical argument. It's a values argument. And it's one that the filesystem, for all its age and simplicity, is uniquely positioned to serve. Not because it's the best technology. But because it's the one technology that already belongs to you.</p><div class="flex justify-between my-5" data-v-80192dbe=""><p></p><h3 data-v-80192dbe="">Previous</h3>
<a href="https://madalitso.me/notes/gaps-in-your-developer-journey" class="font-bold text-primary" data-v-80192dbe="">Gaps in your Developer journey; Can you fix it?</a></div>]]></description>
      <link>https://madalitso.me/notes/why-everyone-is-talking-about-filesystems/</link>
      <guid>https://madalitso.me/notes/why-everyone-is-talking-about-filesystems/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The web is bearable with RSS]]></title>
      <description><![CDATA[<p><br /><a href="https://pluralistic.net/2026/03/07/reader-mode/"><img data-recalc-dims="1" class="xmasthead_link" src="https://i0.wp.com/craphound.com/images/07Mar2026.jpg?w=840&amp;ssl=1" alt="image" /></a></p>

<hr /><p><br /><img data-recalc-dims="1" alt="An anatomical drawing of a cross-section of a man's head. The eyeball has been replaced by an RSS logo. To the left of the face is a 'code waterfall' effect as seen in the credit sequences of the Wachowskis' 'Matrix' movie. To the right are clouds of grey roiling clouds, infiltrating the brain as well." src="https://i0.wp.com/craphound.com/images/rss-view.jpg?w=840&amp;ssl=1" /></p>
<h1>The web is bearable with RSS (<a href="https://pluralistic.net/2026/03/07/reader-mode/#personal-disenshittification">#</a>)</h1>
<p>Never let them tell you that enshittification was a mystery. Enshittification isn't downstream of the "iron laws of economics" or an unrealistic demand by "consumers" to get stuff for free.</p>
<p>Enshittification comes from specific policy choices, made by named individuals, that had the foreseeable and foreseen result of making the web worse:</p>
<p><a href="https://pluralistic.net/2025/10/07/take-it-easy/#but-take-it">https://pluralistic.net/2025/10/07/take-it-easy/#but-take-it</a></p>
<p>Like, there was once a time when an ever-increasing proportion of web users kept tabs on what was going on with RSS. RSS is a simple, powerful way for websites to publish "feeds" of their articles, and for readers to subscribe to those feeds and get notified when something new was posted, and even read that new material right there in your RSS reader tab or app.</p>
<p>RSS is simple and versatile. It's the backbone of podcasts (though Apple and Spotify have done their best to kill it, along with public broadcasters like the BBC, all of whom want you to switch to proprietary apps that spy on you and control you). It's how many automated processes communicate with one another, untouched by human hands. But above all, it's a way to find out when something new has been published on the web.</p>
<p>RSS's liftoff was driven by Google, who released a great RSS reader called "Google Reader" in 2007. Reader was free and reliable, and other RSS readers struggled to compete with it, with the effect that most of us just ended up using Google's product, which made it even harder to launch a competitor.</p>
<p>But in 2013, Google quietly knifed Reader. I've always found the timing suspicious: it came right in the middle of Google's desperate scramble to become Facebook, by means of a product called Google Plus (G+). Famously, Google product managers' bonuses depended on how much G+ engagement they drove, with the effect that every Google product suddenly sprouted G+ buttons that either did something stupid, or something that confusingly duplicated existing functionality (like commenting on Youtube videos).</p>
<p>Google treated G+ as an existential priority, and for good reason. Google was running out of growth potential, having comprehensively conquered Search, and having repeatedly demonstrated that Search was a one-off success, with nearly every other made-in-Google product dying off. What successes Google could claim were far more modest, like Gmail, Google's Hotmail clone. Google augmented its growth by buying other peoples' companies (Blogger, YouTube, Maps, ad-tech, Docs, Android, etc), but its internal initiatives were turkeys.</p>
<p>Eventually, Wall Street was going to conclude that Google had reached the end of its growth period, and Google's shares would fall to a fraction of their value, with a price-to-earnings ratio commensurate with a "mature" company.</p>
<p>Google <em>needed</em> a new growth story, and "Google will conquer Facebook's market" was a pretty good one. After all, investors didn't have to speculate about whether Facebook was profitable, they could just look at Facebook's income statements, which Google proposed to transfer to its own balance sheet. The G+ full-court press was as much a narrative strategy as a business strategy: by tying product managers' bonuses to a metric that demonstrated G+'s rise, Google could convince Wall Street that they had a lot of growth on their horizon.</p>
<p>Of course, tying individual executives' bonuses to making a number go up has a predictably perverse outcome. As Goodhart's law has it, "Any metric becomes a target, and then ceases to be a useful metric." As soon as key decision-makers' personal net worth depending on making the G+ number go up, they crammed G+ <em>everywhere</em> and started to sneak in ways to trigger unintentional G+ sessions. This still happens today – think of how often you accidentally invoke an unbanishable AI feature while using Google's products (and products from rival giant, moribund companies relying on an AI narrative to convince investors that they will continue to grow):</p>
<p><a href="https://pluralistic.net/2025/05/02/kpis-off/#principal-agentic-ai-problem">https://pluralistic.net/2025/05/02/kpis-off/#principal-agentic-ai-problem</a></p>
<p>Like I said, Google Reader died at the peak of Google's scramble to make the G+ number go up. I have a sneaking suspicion that someone at Google realized that Reader's core functionality (helping users discover, share and discuss interesting new web pages) was <em>exactly</em> the kind of thing Google wanted us to use G+ for, and so they killed Reader in a bid to drive us to the stalled-out service they'd bet the company on.</p>
<p>If Google killed Reader in a bid to push users to discover and consume web pages using a proprietary social media service, they succeeded. Unfortunately, the social media service they pushed users into was <em>Facebook</em> – and G+ died shortly thereafter.</p>
<p>For more than a decade, RSS has lain dormant. Many, many websites still emit RSS feeds. It's a default behavior for WordPress sites, for Ghost and Substack sites, for Tumblr and Medium, for Bluesky and Mastodon. You can follow edits to Wikipedia pages by RSS, and also updates to parcels that have been shipped to you through major couriers. Web builders like Jason Kottke continue to surface RSS feeds for elaborate, delightful blogrolls:</p>
<p><a href="https://kottke.org/rolodex/">https://kottke.org/rolodex/</a></p>
<p>There are many good RSS readers. I've been paying for Newsblur since 2011, and consider the $36 I send them every year to be a very good investment:</p>
<p><a href="https://newsblur.com/">https://newsblur.com/</a></p>
<p>But RSS continues to be a power user-coded niche, despite the fact that RSS readers are really easy to set up and – crucially – make <em>using</em> the web <em>much</em> easier. Last week, Caroline Crampton (co-editor of The Browser) wrote about her experiences using RSS:</p>
<p><a href="https://www.carolinecrampton.com/the-view-from-rss/">https://www.carolinecrampton.com/the-view-from-rss/</a></p>
<p>As Crampton points out, much of the web (including some of the cruftiest, most enshittified websites) publish full-text RSS feeds, meaning that you can read their articles right there in your RSS reader, with no ads, no popups, no nag-screens asking you to sign up for a newsletter, verify your age, or submit to their terms of service.</p>
<p>It's almost impossible to overstate how <em>superior</em> RSS is to the median web page. Imagine if the newsletters you followed were rendered with black, clear type on a plain white background (rather than the sadistically infinitesimal, greyed-out type that designers favor thanks to the unkillable urban legend that black type on a white screen causes eye-strain). Imagine reading the web without popups, without ads, without nag screens. Imagine reading the web without interruptors or "keep reading" links.</p>
<p>Now, not every website publishes a fulltext feed. Often, you will just get a teaser, and if you want to read the whole article, you have to click through. I have a few tips for making other websites – even ones like Wired and The Intercept – as easy to read as an RSS reader, at least for Firefox users.</p>
<p>Firefox has a built-in "Reader View" that re-renders the contents of a web-page as black type on a white background. Firefox does some kind of mysterious calculation to determine whether a page can be displayed in Reader View, but you can override this with the Activate Reader View, which adds a Reader View toggle for every page:</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/activate-reader-view/">https://addons.mozilla.org/en-US/firefox/addon/activate-reader-view/</a></p>
<p>Lots of websites (like The Guardian) want you to login before you can read them, and even if you pay to subscribe to them, these sites often want you to re-login every time you visit them (especially if you're running a full suite of privacy blockers). You can skip this whole process by simply toggling Reader View as soon as you get the login pop up. On some websites (like The Verge and Wired), you'll only see the first couple paragraphs of the article in Reader View. But if you then hit reload, the whole article loads.</p>
<p>Activate Reader View puts a Reader View toggle on every page, but clicking that toggle sometimes throws up an error message, when the page is so cursed that Firefox can't figure out what part of it is the article. When this happens, you're stuck reading the page in the site's own default (and usually terrible) view. As you scroll down the page, you will often hit pop-ups that try to get you to sign up for a mailing list, agree to terms of service, or do something else you don't want to do. Rather than hunting for the button to close these pop-ups (or agree to objectionable terms of service), you can install "Kill Sticky," a bookmarklet that reaches into the page's layout files and deletes any element that isn't designed to scroll with the rest of the text:</p>
<p><a href="https://github.com/t-mart/kill-sticky">https://github.com/t-mart/kill-sticky</a></p>
<p>Other websites (like Slashdot and Core77) load computer-destroying Javascript (often as part of an anti-adblock strategy). For these, I use the "Javascript Toggle On and Off" plugin, which lets you create a blacklist of websites that aren't allowed to run any scripts:</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/javascript-toggler/">https://addons.mozilla.org/en-US/firefox/addon/javascript-toggler/</a></p>
<p>Some websites (like Yahoo) load <em>so much crap</em> that they defeat all of these countermeasures. For these websites, I use the "Element Blocker" plug-in, which lets you delete parts of the web-page, either for a single session, or permanently:</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/element-blocker/">https://addons.mozilla.org/en-US/firefox/addon/element-blocker/</a></p>
<p>It's ridiculous that websites put so many barriers up to a pleasant reading experience. A slow-moving avalanche of enshittogenic phenomena got us here. There's corporate enshittification, like Google/Meta's monopolization of ads and Meta/Twitter's crushing of the open web. There's regulatory enshittification, like the EU's failure crack down on companies the pretend that forcing you to click an endless stream of "cookie consent" popups is the same as complying with the GDPR.</p>
<p>Those are real problems, but they don't have to be <em>your</em> problem, at least when you want to read the web. A couple years ago, I wrote a guide to using RSS to improve your web experience, evade lock-in and duck algorithmic recommendation systems:</p>
<p><a href="https://pluralistic.net/2024/10/16/keep-it-really-simple-stupid/#read-receipts-are-you-kidding-me-seriously-fuck-that-noise">https://pluralistic.net/2024/10/16/keep-it-really-simple-stupid/#read-receipts-are-you-kidding-me-seriously-fuck-that-noise</a></p>
<p>Customizing your browser takes this to the next level, disenshittifying many websites – even if they block or restrict RSS. Most of this stuff only applies to desktop browsers, though. Mobile browsers are <em>far</em> more locked down (even mobile Firefox – remember, every iOS browser, including Firefox, is just a re-skinned version of Safari, thanks to Apple's ban rival browser engines). And of course, apps are <em>the worst</em>. An app is just a website skinned in the right kind of IP to make it a crime to improve it in any way:</p>
<p><a href="https://pluralistic.net/2024/05/07/treacherous-computing/#rewilding-the-internet">https://pluralistic.net/2024/05/07/treacherous-computing/#rewilding-the-internet</a></p>
<p>And even if you <em>do</em> customize your mobile browser (Android Firefox lets you do some of this stuff), many apps (Twitter, Tumblr) open external links in their own browser (usually an in-app Chrome instance) with all the bullshit that entails.</p>
<p>The promise of locked-down mobile platforms was that they were going to "just work," without any of the confusing customization options of desktop OSes. It turns out that taking away those confusing customization options was an invitation to every enshittifier to turn the web into an unreadable, extractive, nagging mess. This was the foreseeable – and foreseen – consequence of a new kind of technology where everything that isn't mandatory is prohibited:</p>
<p><a href="https://memex.craphound.com/2010/04/01/why-i-wont-buy-an-ipad-and-think-you-shouldnt-either/">https://memex.craphound.com/2010/04/01/why-i-wont-buy-an-ipad-and-think-you-shouldnt-either/</a></p>
<hr /><h1>Hey look at this (<a href="https://pluralistic.net/2026/03/07/reader-mode/#linkdump">#</a>)</h1>
<p><img data-recalc-dims="1" src="https://i0.wp.com/craphound.com/images/heylookatthis3.jpg?w=840&amp;ssl=1" alt="image" /></p>
<ul><li>The Real Litmus Test for Democratic Presidential Candidates <a href="https://www.hamiltonnolan.com/p/the-real-litmus-test-for-democratic">https://www.hamiltonnolan.com/p/the-real-litmus-test-for-democratic</a></li>
<li>
<p>Users fume over Outlook.com email 'carnage' <a href="https://www.theregister.com/2026/03/04/users_fume_at_outlookcom_email/">https://www.theregister.com/2026/03/04/users_fume_at_outlookcom_email/</a></p>
</li>
<li>
<p>You Bought Zuck’s Ray-Bans. Now Someone in Nairobi Is Watching You Poop. <a href="https://blog.adafruit.com/2026/03/04/you-bought-zucks-ray-bans-now-someone-in-nairobi-is-watching-you-poop/">https://blog.adafruit.com/2026/03/04/you-bought-zucks-ray-bans-now-someone-in-nairobi-is-watching-you-poop/</a></p>
</li>
<li>
<p>Indefinite Book Club Hiatus <a href="https://whatever.scalzi.com/2026/03/03/indefinite-book-club-hiatus/">https://whatever.scalzi.com/2026/03/03/indefinite-book-club-hiatus/</a></p>
</li>
<li>
<p>Art Bits from HyperCard <a href="https://archives.somnolescent.net/web/mari_v2/junk/hypercard/">https://archives.somnolescent.net/web/mari_v2/junk/hypercard/</a></p>
</li>
</ul><hr /><p><br /><img data-recalc-dims="1" alt="A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'" src="https://i0.wp.com/craphound.com/images/worlds-famous-events.png?w=840&amp;ssl=1" /></p>
<h1>Object permanence (<a href="https://pluralistic.net/2026/03/07/reader-mode/#retro">#</a>)</h1>
<p>#25yrsago 200 Eyemodule photos from Disneyland <a href="https://craphound.com/030401/">https://craphound.com/030401/</a></p>
<p>#20yrsago Fourth Amendment luggage tape <a href="https://ideas.4brad.com/node/367">https://ideas.4brad.com/node/367</a></p>
<p>#15yrsago Glenn Beck’s syndicator runs a astroturf-on-demand call-in service for radio programs <a href="https://web.archive.org/web/20110216081007/http://www.tabletmag.com/life-and-religion/58759/radio-daze/">https://web.archive.org/web/20110216081007/http://www.tabletmag.com/life-and-religion/58759/radio-daze/</a></p>
<p>#15yrsago 20 lies from Scott Walker <a href="https://web.archive.org/web/20110308062319/https://filterednews.wordpress.com/2011/03/05/20-lies-and-counting-told-by-gov-walker/">https://web.archive.org/web/20110308062319/https://filterednews.wordpress.com/2011/03/05/20-lies-and-counting-told-by-gov-walker/</a></p>
<p>#10yrsago The correlates of Trumpism: early mortality, lack of education, unemployment, offshored jobs <a href="https://web.archive.org/web/20160415000000*/https://www.washingtonpost.com/news/wonk/wp/2016/03/04/death-predicts-whether-people-vote-for-donald-trump/">https://web.archive.org/web/20160415000000*/https://www.washingtonpost.com/news/wonk/wp/2016/03/04/death-predicts-whether-people-vote-for-donald-trump/</a></p>
<p>#10yrsago Hacking a phone’s fingerprint sensor in 15 mins with $500 worth of inkjet printer and conductive ink <a href="https://web.archive.org/web/20160306194138/http://www.cse.msu.edu/rgroups/biometrics/Publications/Fingerprint/CaoJain_HackingMobilePhonesUsing2DPrintedFingerprint_MSU-CSE-16-2.pdf">https://web.archive.org/web/20160306194138/http://www.cse.msu.edu/rgroups/biometrics/Publications/Fingerprint/CaoJain_HackingMobilePhonesUsing2DPrintedFingerprint_MSU-CSE-16-2.pdf</a></p>
<p>#10yrsago Despite media consensus, Bernie Sanders is raising more money, from more people, than any candidate, ever <a href="https://web.archive.org/web/20160306110848/https://www.washingtonpost.com/politics/sanders-keeps-raising-money--and-spending-it-a-potential-problem-for-clinton/2016/03/05/a8d6d43c-e2eb-11e5-8d98-4b3d9215ade1_story.html">https://web.archive.org/web/20160306110848/https://www.washingtonpost.com/politics/sanders-keeps-raising-money–and-spending-it-a-potential-problem-for-clinton/2016/03/05/a8d6d43c-e2eb-11e5-8d98-4b3d9215ade1_story.html</a></p>
<p>#10yrsago Calculating US police killings using methodologies from war-crimes trials <a href="https://granta.com/violence-in-blue/">https://granta.com/violence-in-blue/</a></p>
<p>#1yrago Brother makes a demon-haunted printer <a href="https://pluralistic.net/2025/03/05/printers-devil/#show-me-the-incentives-i-will-show-you-the-outcome">https://pluralistic.net/2025/03/05/printers-devil/#show-me-the-incentives-i-will-show-you-the-outcome</a></p>
<p>#1yrago Two weak spots in Big Tech economics <a href="https://pluralistic.net/2025/03/06/privacy-last/#exceptionally-american">https://pluralistic.net/2025/03/06/privacy-last/#exceptionally-american</a></p>
<hr /><h1>Upcoming appearances (<a href="https://pluralistic.net/2026/03/07/reader-mode/#upcoming">#</a>)</h1>
<p><img data-recalc-dims="1" alt="A photo of me onstage, giving a speech, pounding the podium." src="https://i0.wp.com/craphound.com/images/appearances3.jpg?w=840&amp;ssl=1" /></p>
<ul><li>San Francisco: Launch for Cindy Cohn's "Privacy's Defender" (City Lights), Mar 10<br /><a href="https://citylights.com/events/cindy-cohn-launch-party-for-privacys-defender/">https://citylights.com/events/cindy-cohn-launch-party-for-privacys-defender/</a></li>
<li>
<p>Barcelona: Enshittification with Simona Levi/Xnet (Llibreria Finestres), Mar 20<br /><a href="https://www.llibreriafinestres.com/evento/cory-doctorow/">https://www.llibreriafinestres.com/evento/cory-doctorow/</a></p>
</li>
<li>
<p>Berkeley: Bioneers keynote, Mar 27<br /><a href="https://conference.bioneers.org/">https://conference.bioneers.org/</a></p>
</li>
<li>
<p>Montreal: Bronfman Lecture (McGill) Apr 10<br /><a href="https://www.eventbrite.ca/e/artificial-intelligence-the-ultimate-disrupter-tickets-1982706623885">https://www.eventbrite.ca/e/artificial-intelligence-the-ultimate-disrupter-tickets-1982706623885</a></p>
</li>
<li>
<p>London: Resisting Big Tech Empires (LSBU)<br /><a href="https://www.tickettailor.com/events/globaljusticenow/2042691">https://www.tickettailor.com/events/globaljusticenow/2042691</a></p>
</li>
<li>
<p>Berlin: Re:publica, May 18-20<br /><a href="https://re-publica.com/de/news/rp26-sprecher-cory-doctorow">https://re-publica.com/de/news/rp26-sprecher-cory-doctorow</a></p>
</li>
<li>
<p>Berlin: Enshittification at Otherland Books, May 19<br /><a href="https://www.otherland-berlin.de/de/event-details/cory-doctorow.html">https://www.otherland-berlin.de/de/event-details/cory-doctorow.html</a></p>
</li>
<li>
<p>Hay-on-Wye: HowTheLightGetsIn, May 22-25<br /><a href="https://howthelightgetsin.org/festivals/hay/big-ideas-2">https://howthelightgetsin.org/festivals/hay/big-ideas-2</a></p>
</li>
</ul><hr /><p><br /><img data-recalc-dims="1" alt="A screenshot of me at my desk, doing a livecast." src="https://i0.wp.com/craphound.com/images/recentappearances3.jpg?w=840&amp;ssl=1" /></p>
<h1>Recent appearances (<a href="https://pluralistic.net/2026/03/07/reader-mode/#recent">#</a>)</h1>
<ul><li>The Virtual Jewel Box (U Utah)<br /><a href="https://tanner.utah.edu/podcast/enshittification-cory-doctorow-matthew-potolsky/">https://tanner.utah.edu/podcast/enshittification-cory-doctorow-matthew-potolsky/</a></li>
<li>
<p>Tanner Humanities Lecture (U Utah)<br /><a href="https://www.youtube.com/watch?v=i6Yf1nSyekI">https://www.youtube.com/watch?v=i6Yf1nSyekI</a></p>
</li>
<li>
<p>The Lost Cause<br /><a href="https://streets.mn/2026/03/02/book-club-the-lost-cause/">https://streets.mn/2026/03/02/book-club-the-lost-cause/</a></p>
</li>
<li>
<p>Should Democrats Make A Nuremberg Caucus? (Make It Make Sense)<br /><a href="https://www.youtube.com/watch?v=MWxKrnNfrlo">https://www.youtube.com/watch?v=MWxKrnNfrlo</a></p>
</li>
<li>
<p>Making The Internet Suck Less (Thinking With Mitch Joel)<br /><a href="https://www.sixpixels.com/podcast/archives/making-the-internet-suck-less-with-cory-doctorow-twmj-1024/">https://www.sixpixels.com/podcast/archives/making-the-internet-suck-less-with-cory-doctorow-twmj-1024/</a></p>
</li>
</ul><hr /><p><br /><img data-recalc-dims="1" alt="A grid of my books with Will Stahle covers.." src="https://i0.wp.com/craphound.com/images/recent.jpg?w=840&amp;ssl=1" /></p>
<h1>Latest books (<a href="https://pluralistic.net/2026/03/07/reader-mode/#latest">#</a>)</h1>
<ul><li>"Canny Valley": A limited edition collection of the collages I create for Pluralistic, self-published, September 2025 <a href="https://pluralistic.net/2025/09/04/illustrious/#chairman-bruce">https://pluralistic.net/2025/09/04/illustrious/#chairman-bruce</a></li>
<li>
<p>"Enshittification: Why Everything Suddenly Got Worse and What to Do About It," Farrar, Straus, Giroux, October 7 2025<br /><a href="https://us.macmillan.com/books/9780374619329/enshittification/">https://us.macmillan.com/books/9780374619329/enshittification/</a></p>
</li>
<li>
<p>"Picks and Shovels": a sequel to "Red Team Blues," about the heroic era of the PC, Tor Books (US), Head of Zeus (UK), February 2025 (<a href="https://us.macmillan.com/books/9781250865908/picksandshovels">https://us.macmillan.com/books/9781250865908/picksandshovels</a>).</p>
</li>
<li>
<p>"The Bezzle": a sequel to "Red Team Blues," about prison-tech and other grifts, Tor Books (US), Head of Zeus (UK), February 2024 (<a href="http://thebezzle.org">thebezzle.org</a>).</p>
</li>
<li>
<p>"The Lost Cause:" a solarpunk novel of hope in the climate emergency, Tor Books (US), Head of Zeus (UK), November 2023 (<a href="http://lost-cause.org">http://lost-cause.org</a>).</p>
</li>
<li>
<p>"The Internet Con": A nonfiction book about interoperability and Big Tech (Verso) September 2023 (<a href="http://seizethemeansofcomputation.org">http://seizethemeansofcomputation.org</a>). Signed copies at Book Soup (<a href="https://www.booksoup.com/book/9781804291245">https://www.booksoup.com/book/9781804291245</a>).</p>
</li>
<li>
<p>"Red Team Blues": "A grabby, compulsive thriller that will leave you knowing more about how the world works than you did before." Tor Books <a href="http://redteamblues.com">http://redteamblues.com</a>.</p>
</li>
<li>
<p>"Chokepoint Capitalism: How to Beat Big Tech, Tame Big Content, and Get Artists Paid, with Rebecca Giblin", on how to unrig the markets for creative labor, Beacon Press/Scribe 2022 <a href="https://chokepointcapitalism.com">https://chokepointcapitalism.com</a></p>
</li>
</ul><hr /><p><br /><img data-recalc-dims="1" alt="A cardboard book box with the Macmillan logo." src="https://i0.wp.com/craphound.com/images/upcoming-books.jpg?w=840&amp;ssl=1" /></p>
<h1>Upcoming books (<a href="https://pluralistic.net/2026/03/07/reader-mode/#upcoming-books">#</a>)</h1>
<ul><li>"The Reverse-Centaur's Guide to AI," a short book about being a better AI critic, Farrar, Straus and Giroux, June 2026</li>
<li>
<p>"Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2026</p>
</li>
<li>
<p>"The Post-American Internet," a geopolitical sequel of sorts to <em>Enshittification</em>, Farrar, Straus and Giroux, 2027</p>
</li>
<li>
<p>"Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, 2027</p>
</li>
<li>
<p>"The Memex Method," Farrar, Straus, Giroux, 2027</p>
</li>
</ul><hr /><p><br /><img data-recalc-dims="1" src="https://i0.wp.com/craphound.com/images/colophon2.jpg?w=840&amp;ssl=1" alt="image" /></p>
<h1>Colophon (<a href="https://pluralistic.net/2026/03/07/reader-mode/#bragsheet">#</a>)</h1>
<p>Today's top sources:</p>
<p><strong>Currently writing: "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America (1012 words today, 45361 total)</strong></p>
<ul><li>"The Reverse Centaur's Guide to AI," a short book for Farrar, Straus and Giroux about being an effective AI critic. LEGAL REVIEW AND COPYEDIT COMPLETE.</li>
<li>
<p>"The Post-American Internet," a short book about internet policy in the age of Trumpism. PLANNING.</p>
</li>
<li>
<p>A Little Brother short story about DIY insulin PLANNING</p>
</li>
</ul>]]></description>
      <link>https://pluralistic.net/2026/03/07/reader-mode/</link>
      <guid>https://pluralistic.net/2026/03/07/reader-mode/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[GitHub - BigBodyCobain/Shadowbroker: Open-source intelligence for the global theater. Track everything from the corporate/private jets of the wealthy, and spy satellites, to seismic events in one unified interface. The knowledge is available to all but ra]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><p align="center" dir="auto">
  </p><div class="markdown-heading" dir="auto"><h1 align="center" class="heading-element" dir="auto">🛰️ S H A D O W B R O K E R</h1><a id="user-content-️-s-h-a-d-o-w-b-r-o-k-e-r" class="anchor" aria-label="Permalink: 🛰️ S H A D O W B R O K E R" href="#️-s-h-a-d-o-w-b-r-o-k-e-r"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
  <p align="center" dir="auto"><strong>Global Threat Intercept — Real-Time Geospatial Intelligence Platform</strong></p>
  <p align="center" dir="auto">
  </p>
<p dir="auto"></p>
<hr>
<details open="" class="details-reset border rounded-2">
  <summary class="tmp-px-3 py-2">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-camera-video">
    <path d="M16 3.75v8.5a.75.75 0 0 1-1.136.643L11 10.575v.675A1.75 1.75 0 0 1 9.25 13h-7.5A1.75 1.75 0 0 1 0 11.25v-6.5C0 3.784.784 3 1.75 3h7.5c.966 0 1.75.784 1.75 1.75v.675l3.864-2.318A.75.75 0 0 1 16 3.75Zm-6.5 1a.25.25 0 0 0-.25-.25h-7.5a.25.25 0 0 0-.25.25v6.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-6.5ZM11 8.825l3.5 2.1v-5.85l-3.5 2.1Z"></path>
</svg>
    <span class="m-1">SHADOWBROKER_LOG1423.MP4</span>
    <span class="dropdown-caret"></span>
  </summary>

  <video src="https://private-user-images.githubusercontent.com/43977454/561849245-248208ec-62f7-49d1-831d-4bd0a1fa6852.MP4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzNjc1MzUsIm5iZiI6MTc3MzM2NzIzNSwicGF0aCI6Ii80Mzk3NzQ1NC81NjE4NDkyNDUtMjQ4MjA4ZWMtNjJmNy00OWQxLTgzMWQtNGJkMGExZmE2ODUyLk1QND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEzVDAyMDAzNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTNmYTA5MTk2NTBlYWVlNGMwZDQwOGI2MDgyYTVkNDhkYzgxZDM5YjY4NmE5NGUwZmFhOWMyODFiMjNkNTUzM2QmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.ZFOfGycS7Tnm8_FBAhiqIHGZaZpEye7Tjdt1cMAAxEw" data-canonical-src="https://private-user-images.githubusercontent.com/43977454/561849245-248208ec-62f7-49d1-831d-4bd0a1fa6852.MP4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzNjc1MzUsIm5iZiI6MTc3MzM2NzIzNSwicGF0aCI6Ii80Mzk3NzQ1NC81NjE4NDkyNDUtMjQ4MjA4ZWMtNjJmNy00OWQxLTgzMWQtNGJkMGExZmE2ODUyLk1QND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEzVDAyMDAzNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTNmYTA5MTk2NTBlYWVlNGMwZDQwOGI2MDgyYTVkNDhkYzgxZDM5YjY4NmE5NGUwZmFhOWMyODFiMjNkNTUzM2QmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.ZFOfGycS7Tnm8_FBAhiqIHGZaZpEye7Tjdt1cMAAxEw" controls="controls" muted="muted" class="d-block rounded-bottom-2 border-top width-fit" style="max-height:640px; min-height: 200px">

  </video>
</details>

<p dir="auto"><strong>ShadowBroker</strong> is a real-time, multi-domain OSINT dashboard that aggregates live data from dozens of open-source intelligence feeds and renders them on a unified dark-ops map interface. It tracks aircraft, ships, satellites, earthquakes, conflict zones, CCTV networks, GPS jamming, and breaking geopolitical events — all updating in real time.</p>
<p dir="auto">Built with <strong>Next.js</strong>, <strong>MapLibre GL</strong>, <strong>FastAPI</strong>, and <strong>Python</strong>, it's designed for analysts, researchers, and enthusiasts who want a single-pane-of-glass view of global activity.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Interesting Use Cases</h2><a id="user-content-interesting-use-cases" class="anchor" aria-label="Permalink: Interesting Use Cases" href="#interesting-use-cases"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Track everything from Air Force One to the private jets of billionaires, dictators, and corporations</li>
<li>Monitor satellites passing overhead and see high-resolution satellite imagery</li>
<li>Nose around local emergency scanners</li>
<li>Watch naval traffic worldwide</li>
<li>Detect GPS jamming zones</li>
<li>Follow earthquakes and other natural disasters in real time</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">⚡ Quick Start (Docker or Podman)</h2><a id="user-content--quick-start-docker-or-podman" class="anchor" aria-label="Permalink: ⚡ Quick Start (Docker or Podman)" href="#-quick-start-docker-or-podman"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Linux/Mac</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/BigBodyCobain/Shadowbroker.git
cd Shadowbroker
./compose.sh up -d"><pre>git clone https://github.com/BigBodyCobain/Shadowbroker.git
<span class="pl-c1">cd</span> Shadowbroker
./compose.sh up -d</pre></div>
<p dir="auto">Windows</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/BigBodyCobain/Shadowbroker.git
cd Shadowbroker
docker-compose up -d"><pre>git clone https://github.com/BigBodyCobain/Shadowbroker.git
<span class="pl-c1">cd</span> Shadowbroker
docker-compose up -d</pre></div>
<p dir="auto">Open <code>http://localhost:3000</code> to view the dashboard! <em>(Requires Docker or Podman)</em></p>
<p dir="auto"><code>compose.sh</code> auto-detects <code>docker compose</code>, <code>docker-compose</code>, <code>podman compose</code>, and <code>podman-compose</code>.
If both runtimes are installed, you can force Podman with <code>./compose.sh --engine podman up -d</code>.
Do not append a trailing <code>.</code> to that command; Compose treats it as a service name.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">✨ Features</h2><a id="user-content--features" class="anchor" aria-label="Permalink: ✨ Features" href="#-features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🛩️ Aviation Tracking</h3><a id="user-content-️-aviation-tracking" class="anchor" aria-label="Permalink: 🛩️ Aviation Tracking" href="#️-aviation-tracking"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Commercial Flights</strong> — Real-time positions via OpenSky Network (~5,000+ aircraft)</li>
<li><strong>Private Aircraft</strong> — Light GA, turboprops, bizjets tracked separately</li>
<li><strong>Private Jets</strong> — High-net-worth individual aircraft with owner identification</li>
<li><strong>Military Flights</strong> — Tankers, ISR, fighters, transports via adsb.lol military endpoint</li>
<li><strong>Flight Trail Accumulation</strong> — Persistent breadcrumb trails for all tracked aircraft</li>
<li><strong>Holding Pattern Detection</strong> — Automatically flags aircraft circling (&gt;300° total turn)</li>
<li><strong>Aircraft Classification</strong> — Shape-accurate SVG icons: airliners, turboprops, bizjets, helicopters</li>
<li><strong>Grounded Detection</strong> — Aircraft below 100ft AGL rendered with grey icons</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🚢 Maritime Tracking</h3><a id="user-content--maritime-tracking" class="anchor" aria-label="Permalink: 🚢 Maritime Tracking" href="#-maritime-tracking"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>AIS Vessel Stream</strong> — 25,000+ vessels via aisstream.io WebSocket (real-time)</li>
<li><strong>Ship Classification</strong> — Cargo, tanker, passenger, yacht, military vessel types with color-coded icons</li>
<li><strong>Carrier Strike Group Tracker</strong> — All 11 active US Navy aircraft carriers with OSINT-estimated positions
<ul dir="auto">
<li>Automated GDELT news scraping for carrier movement intelligence</li>
<li>50+ geographic region-to-coordinate mappings</li>
<li>Disk-cached positions, auto-updates at 00:00 &amp; 12:00 UTC</li>
</ul>
</li>
<li><strong>Cruise &amp; Passenger Ships</strong> — Dedicated layer for cruise liners and ferries</li>
<li><strong>Clustered Display</strong> — Ships cluster at low zoom with count labels, decluster on zoom-in</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🛰️ Space &amp; Satellites</h3><a id="user-content-️-space--satellites" class="anchor" aria-label="Permalink: 🛰️ Space &amp; Satellites" href="#️-space--satellites"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Orbital Tracking</strong> — Real-time satellite positions via CelesTrak TLE data + SGP4 propagation (2,000+ active satellites, no API key required)</li>
<li><strong>Mission-Type Classification</strong> — Color-coded by mission: military recon (red), SAR (cyan), SIGINT (white), navigation (blue), early warning (magenta), commercial imaging (green), space station (gold)</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🌍 Geopolitics &amp; Conflict</h3><a id="user-content--geopolitics--conflict" class="anchor" aria-label="Permalink: 🌍 Geopolitics &amp; Conflict" href="#-geopolitics--conflict"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Global Incidents</strong> — GDELT-powered conflict event aggregation (last 8 hours, ~1,000 events)</li>
<li><strong>Ukraine Frontline</strong> — Live warfront GeoJSON from DeepState Map</li>
<li><strong>SIGINT/RISINT News Feed</strong> — Real-time RSS aggregation from multiple intelligence-focused sources with user-customizable feeds (up to 20 sources, configurable priority weights 1-5)</li>
<li><strong>Region Dossier</strong> — Right-click anywhere on the map for:
<ul dir="auto">
<li>Country profile (population, capital, languages, currencies, area)</li>
<li>Head of state &amp; government type (Wikidata SPARQL)</li>
<li>Local Wikipedia summary with thumbnail</li>
</ul>
</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🛰️ Satellite Imagery</h3><a id="user-content-️-satellite-imagery" class="anchor" aria-label="Permalink: 🛰️ Satellite Imagery" href="#️-satellite-imagery"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>NASA GIBS (MODIS Terra)</strong> — Daily true-color satellite imagery overlay with 30-day time slider, play/pause animation, and opacity control (~250m/pixel)</li>
<li><strong>High-Res Satellite (Esri)</strong> — Sub-meter resolution imagery via Esri World Imagery — zoom into buildings and terrain detail (zoom 18+)</li>
<li><strong>Sentinel-2 Intel Card</strong> — Right-click anywhere on the map for a floating intel card showing the latest Sentinel-2 satellite photo with capture date, cloud cover %, and clickable full-resolution image (10m resolution, updated every ~5 days)</li>
<li><strong>SATELLITE Style Preset</strong> — Quick-toggle high-res imagery via the STYLE button (DEFAULT → SATELLITE → FLIR → NVG → CRT)</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">📻 Software-Defined Radio (SDR)</h3><a id="user-content--software-defined-radio-sdr" class="anchor" aria-label="Permalink: 📻 Software-Defined Radio (SDR)" href="#-software-defined-radio-sdr"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>KiwiSDR Receivers</strong> — 500+ public SDR receivers plotted worldwide with clustered amber markers</li>
<li><strong>Live Radio Tuner</strong> — Click any KiwiSDR node to open an embedded SDR tuner directly in the SIGINT panel</li>
<li><strong>Metadata Display</strong> — Node name, location, antenna type, frequency bands, active users</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">📷 Surveillance</h3><a id="user-content--surveillance" class="anchor" aria-label="Permalink: 📷 Surveillance" href="#-surveillance"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>CCTV Mesh</strong> — 2,000+ live traffic cameras from:
<ul dir="auto">
<li>🇬🇧 Transport for London JamCams</li>
<li>🇺🇸 Austin, TX TxDOT</li>
<li>🇺🇸 NYC DOT</li>
<li>🇸🇬 Singapore LTA</li>
<li>Custom URL ingestion</li>
</ul>
</li>
<li><strong>Feed Rendering</strong> — Automatic detection &amp; rendering of video, MJPEG, HLS, embed, satellite tile, and image feeds</li>
<li><strong>Clustered Map Display</strong> — Green dots cluster with count labels, decluster on zoom</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">📡 Signal Intelligence</h3><a id="user-content--signal-intelligence" class="anchor" aria-label="Permalink: 📡 Signal Intelligence" href="#-signal-intelligence"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>GPS Jamming Detection</strong> — Real-time analysis of aircraft NAC-P (Navigation Accuracy Category) values
<ul dir="auto">
<li>Grid-based aggregation identifies interference zones</li>
<li>Red overlay squares with "GPS JAM XX%" severity labels</li>
</ul>
</li>
<li><strong>Radio Intercept Panel</strong> — Scanner-style UI for monitoring communications</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🔥 Environmental &amp; Infrastructure Monitoring</h3><a id="user-content--environmental--infrastructure-monitoring" class="anchor" aria-label="Permalink: 🔥 Environmental &amp; Infrastructure Monitoring" href="#-environmental--infrastructure-monitoring"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>NASA FIRMS Fire Hotspots (24h)</strong> — 5,000+ global thermal anomalies from NOAA-20 VIIRS satellite, updated every cycle. Flame-shaped icons color-coded by fire radiative power (FRP): yellow (low), orange, red, dark red (intense). Clustered at low zoom with fire-shaped cluster markers.</li>
<li><strong>Space Weather Badge</strong> — Live NOAA geomagnetic storm indicator in the bottom status bar. Color-coded Kp index: green (quiet), yellow (active), red (storm G1–G5). Data from SWPC planetary K-index 1-minute feed.</li>
<li><strong>Internet Outage Monitoring</strong> — Regional internet connectivity alerts from Georgia Tech IODA. Grey markers at affected regions with severity percentage. Uses only reliable datasources (BGP routing tables, active ping probing) — no telescope or interpolated data.</li>
<li><strong>Data Center Mapping</strong> — 2,000+ global data centers plotted from a curated dataset. Clustered purple markers with server-rack icons. Click for operator, location, and automatic internet outage cross-referencing by country.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🌐 Additional Layers</h3><a id="user-content--additional-layers" class="anchor" aria-label="Permalink: 🌐 Additional Layers" href="#-additional-layers"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Earthquakes (24h)</strong> — USGS real-time earthquake feed with magnitude-scaled markers</li>
<li><strong>Day/Night Cycle</strong> — Solar terminator overlay showing global daylight/darkness</li>
<li><strong>Global Markets Ticker</strong> — Live financial market indices (minimizable)</li>
<li><strong>Measurement Tool</strong> — Point-to-point distance &amp; bearing measurement on the map</li>
<li><strong>LOCATE Bar</strong> — Search by coordinates (31.8, 34.8) or place name (Tehran, Strait of Hormuz) to fly directly to any location — geocoded via OpenStreetMap Nominatim</li>
</ul>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/43977454/560648186-f2c953b2-3528-4360-af5a-7ea34ff28489.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzNjc1MzUsIm5iZiI6MTc3MzM2NzIzNSwicGF0aCI6Ii80Mzk3NzQ1NC81NjA2NDgxODYtZjJjOTUzYjItMzUyOC00MzYwLWFmNWEtN2VhMzRmZjI4NDg5LmpwZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEzVDAyMDAzNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTM2ZDY2OWRkZWVmMWZiNmIxYzczZGM5YTgyY2VmYTIzZjI5N2NkYjA3ZGYwNTEwOGU0YzQ2NDA0MmFjYjViYTQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.mTmzSLUOiTWJDaIoCFXCeNAEmUYxb4tMFlQl1r6D_HM"><img src="https://private-user-images.githubusercontent.com/43977454/560648186-f2c953b2-3528-4360-af5a-7ea34ff28489.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzMzNjc1MzUsIm5iZiI6MTc3MzM2NzIzNSwicGF0aCI6Ii80Mzk3NzQ1NC81NjA2NDgxODYtZjJjOTUzYjItMzUyOC00MzYwLWFmNWEtN2VhMzRmZjI4NDg5LmpwZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzEzVDAyMDAzNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTM2ZDY2OWRkZWVmMWZiNmIxYzczZGM5YTgyY2VmYTIzZjI5N2NkYjA3ZGYwNTEwOGU0YzQ2NDA0MmFjYjViYTQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.mTmzSLUOiTWJDaIoCFXCeNAEmUYxb4tMFlQl1r6D_HM" alt="Gaza" style="max-width: 100%;"></a></p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🏗️ Architecture</h2><a id="user-content-️-architecture" class="anchor" aria-label="Permalink: 🏗️ Architecture" href="#️-architecture"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="┌────────────────────────────────────────────────────────┐
│                   FRONTEND (Next.js)                   │
│                                                        │
│  ┌─────────────┐    ┌──────────┐    ┌───────────────┐  │
│  │ MapLibre GL │    │ NewsFeed │    │ Control Panels│  │
│  │  2D WebGL   │    │  SIGINT  │    │ Layers/Filters│  │
│  │ Map Render  │    │  Intel   │    │ Markets/Radio │  │
│  └──────┬──────┘    └────┬─────┘    └───────┬───────┘  │
│         └────────────────┼──────────────────┘          │
│                          │ REST API (60s / 120s)       │
├──────────────────────────┼─────────────────────────────┤
│                    BACKEND (FastAPI)                   │
│                          │                             │
│  ┌───────────────────────┼──────────────────────────┐  │
│  │               Data Fetcher (Scheduler)           │  │
│  │                                                  │  │
│  │  ┌──────────┬──────────┬──────────┬───────────┐  │  │
│  │  │ OpenSky  │ adsb.lol │CelesTrak │   USGS    │  │  │
│  │  │ Flights  │ Military │   Sats   │  Quakes   │  │  │
│  │  ├──────────┼──────────┼──────────┼───────────┤  │  │
│  │  │  AIS WS  │ Carrier  │  GDELT   │   CCTV    │  │  │
│  │  │  Ships   │ Tracker  │ Conflict │  Cameras  │  │  │
│  │  ├──────────┼──────────┼──────────┼───────────┤  │  │
│  │  │ DeepState│   RSS    │  Region  │    GPS    │  │  │
│  │  │ Frontline│  Intel   │ Dossier  │  Jamming  │  │  │
│  │  ├──────────┼──────────┼──────────┼───────────┤  │  │
│  │  │  NASA    │  NOAA    │  IODA    │  KiwiSDR  │  │  │
│  │  │  FIRMS   │  Space Wx│ Outages  │  Radios   │  │  │
│  │  └──────────┴──────────┴──────────┴───────────┘  │  │
│  └──────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────┘"><pre class="notranslate"><code>┌────────────────────────────────────────────────────────┐
│                   FRONTEND (Next.js)                   │
│                                                        │
│  ┌─────────────┐    ┌──────────┐    ┌───────────────┐  │
│  │ MapLibre GL │    │ NewsFeed │    │ Control Panels│  │
│  │  2D WebGL   │    │  SIGINT  │    │ Layers/Filters│  │
│  │ Map Render  │    │  Intel   │    │ Markets/Radio │  │
│  └──────┬──────┘    └────┬─────┘    └───────┬───────┘  │
│         └────────────────┼──────────────────┘          │
│                          │ REST API (60s / 120s)       │
├──────────────────────────┼─────────────────────────────┤
│                    BACKEND (FastAPI)                   │
│                          │                             │
│  ┌───────────────────────┼──────────────────────────┐  │
│  │               Data Fetcher (Scheduler)           │  │
│  │                                                  │  │
│  │  ┌──────────┬──────────┬──────────┬───────────┐  │  │
│  │  │ OpenSky  │ adsb.lol │CelesTrak │   USGS    │  │  │
│  │  │ Flights  │ Military │   Sats   │  Quakes   │  │  │
│  │  ├──────────┼──────────┼──────────┼───────────┤  │  │
│  │  │  AIS WS  │ Carrier  │  GDELT   │   CCTV    │  │  │
│  │  │  Ships   │ Tracker  │ Conflict │  Cameras  │  │  │
│  │  ├──────────┼──────────┼──────────┼───────────┤  │  │
│  │  │ DeepState│   RSS    │  Region  │    GPS    │  │  │
│  │  │ Frontline│  Intel   │ Dossier  │  Jamming  │  │  │
│  │  ├──────────┼──────────┼──────────┼───────────┤  │  │
│  │  │  NASA    │  NOAA    │  IODA    │  KiwiSDR  │  │  │
│  │  │  FIRMS   │  Space Wx│ Outages  │  Radios   │  │  │
│  │  └──────────┴──────────┴──────────┴───────────┘  │  │
│  └──────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────┘
</code></pre></div>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📊 Data Sources &amp; APIs</h2><a id="user-content--data-sources--apis" class="anchor" aria-label="Permalink: 📊 Data Sources &amp; APIs" href="#-data-sources--apis"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Source</th>
<th>Data</th>
<th>Update Frequency</th>
<th>API Key Required</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://opensky-network.org" rel="nofollow">OpenSky Network</a></td>
<td>Commercial &amp; private flights</td>
<td>~60s</td>
<td>Optional (anonymous limited)</td>
</tr>
<tr>
<td><a href="https://adsb.lol" rel="nofollow">adsb.lol</a></td>
<td>Military aircraft</td>
<td>~60s</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://aisstream.io" rel="nofollow">aisstream.io</a></td>
<td>AIS vessel positions</td>
<td>Real-time WebSocket</td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td><a href="https://celestrak.org" rel="nofollow">CelesTrak</a></td>
<td>Satellite orbital positions (TLE + SGP4)</td>
<td>~60s</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://earthquake.usgs.gov" rel="nofollow">USGS Earthquake</a></td>
<td>Global seismic events</td>
<td>~60s</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://www.gdeltproject.org" rel="nofollow">GDELT Project</a></td>
<td>Global conflict events</td>
<td>~6h</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://deepstatemap.live" rel="nofollow">DeepState Map</a></td>
<td>Ukraine frontline</td>
<td>~30min</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://api.tfl.gov.uk" rel="nofollow">Transport for London</a></td>
<td>London CCTV JamCams</td>
<td>~5min</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://its.txdot.gov" rel="nofollow">TxDOT</a></td>
<td>Austin TX traffic cameras</td>
<td>~5min</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://webcams.nyctmc.org" rel="nofollow">NYC DOT</a></td>
<td>NYC traffic cameras</td>
<td>~5min</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://datamall.lta.gov.sg" rel="nofollow">Singapore LTA</a></td>
<td>Singapore traffic cameras</td>
<td>~5min</td>
<td><strong>Yes</strong></td>
</tr>
<tr>
<td><a href="https://restcountries.com" rel="nofollow">RestCountries</a></td>
<td>Country profile data</td>
<td>On-demand (cached 24h)</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://query.wikidata.org" rel="nofollow">Wikidata SPARQL</a></td>
<td>Head of state data</td>
<td>On-demand (cached 24h)</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://en.wikipedia.org/api" rel="nofollow">Wikipedia API</a></td>
<td>Location summaries &amp; aircraft images</td>
<td>On-demand (cached)</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://gibs.earthdata.nasa.gov" rel="nofollow">NASA GIBS</a></td>
<td>MODIS Terra daily satellite imagery</td>
<td>Daily (24-48h delay)</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://www.arcgis.com" rel="nofollow">Esri World Imagery</a></td>
<td>High-res satellite basemap</td>
<td>Static (periodically updated)</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://planetarycomputer.microsoft.com" rel="nofollow">MS Planetary Computer</a></td>
<td>Sentinel-2 L2A scenes (right-click)</td>
<td>On-demand</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://kiwisdr.com" rel="nofollow">KiwiSDR</a></td>
<td>Public SDR receiver locations</td>
<td>~30min</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://nominatim.openstreetmap.org" rel="nofollow">OSM Nominatim</a></td>
<td>Place name geocoding (LOCATE bar)</td>
<td>On-demand</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://firms.modaps.eosdis.nasa.gov" rel="nofollow">NASA FIRMS</a></td>
<td>NOAA-20 VIIRS fire/thermal hotspots</td>
<td>~120s</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://services.swpc.noaa.gov" rel="nofollow">NOAA SWPC</a></td>
<td>Space weather Kp index &amp; solar events</td>
<td>~120s</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://ioda.inetintel.cc.gatech.edu" rel="nofollow">IODA (Georgia Tech)</a></td>
<td>Regional internet outage alerts</td>
<td>~120s</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://github.com/Ringmast4r/Data-Center-Map---Global">DC Map (GitHub)</a></td>
<td>Global data center locations</td>
<td>Static (cached 7d)</td>
<td>No</td>
</tr>
<tr>
<td><a href="https://carto.com" rel="nofollow">CARTO Basemaps</a></td>
<td>Dark map tiles</td>
<td>Continuous</td>
<td>No</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🚀 Getting Started</h2><a id="user-content--getting-started" class="anchor" aria-label="Permalink: 🚀 Getting Started" href="#-getting-started"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🐳 Docker / Podman Setup (Recommended for Self-Hosting)</h3><a id="user-content--docker--podman-setup-recommended-for-self-hosting" class="anchor" aria-label="Permalink: 🐳 Docker / Podman Setup (Recommended for Self-Hosting)" href="#-docker--podman-setup-recommended-for-self-hosting"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The repo includes a <code>docker-compose.yml</code> that builds both images locally.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/BigBodyCobain/Shadowbroker.git
cd Shadowbroker
# Add your API keys in a repo-root .env file (optional — see Environment Variables below)
./compose.sh up -d"><pre>git clone https://github.com/BigBodyCobain/Shadowbroker.git
<span class="pl-c1">cd</span> Shadowbroker
<span class="pl-c"><span class="pl-c">#</span> Add your API keys in a repo-root .env file (optional — see Environment Variables below)</span>
./compose.sh up -d</pre></div>
<p dir="auto">Open <code>http://localhost:3000</code> to view the dashboard.</p>
<blockquote>
<p dir="auto"><strong>Deploying publicly or on a LAN?</strong> No configuration needed for most setups.
The frontend proxies all API calls through the Next.js server to <code>BACKEND_URL</code>,
which defaults to <code>http://backend:8000</code> (Docker internal networking).
Port 8000 does not need to be exposed externally.</p>
<p dir="auto">If your backend runs on a <strong>different host or port</strong>, set <code>BACKEND_URL</code> at runtime — no rebuild required:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Linux / macOS
BACKEND_URL=http://myserver.com:9096 docker-compose up -d

# Podman (via compose.sh wrapper)
BACKEND_URL=http://192.168.1.50:9096 ./compose.sh up -d

# Windows (PowerShell)
$env:BACKEND_URL=&quot;http://myserver.com:9096&quot;; docker-compose up -d

# Or add to a .env file next to docker-compose.yml:
# BACKEND_URL=http://myserver.com:9096"><pre><span class="pl-c"><span class="pl-c">#</span> Linux / macOS</span>
BACKEND_URL=http://myserver.com:9096 docker-compose up -d

<span class="pl-c"><span class="pl-c">#</span> Podman (via compose.sh wrapper)</span>
BACKEND_URL=http://192.168.1.50:9096 ./compose.sh up -d

<span class="pl-c"><span class="pl-c">#</span> Windows (PowerShell)</span>
<span class="pl-smi">$env</span>:BACKEND_URL=<span class="pl-s"><span class="pl-pds">"</span>http://myserver.com:9096<span class="pl-pds">"</span></span><span class="pl-k">;</span> docker-compose up -d

<span class="pl-c"><span class="pl-c">#</span> Or add to a .env file next to docker-compose.yml:</span>
<span class="pl-c"><span class="pl-c">#</span> BACKEND_URL=http://myserver.com:9096</span></pre></div>
</blockquote>
<p dir="auto">If you prefer to call the container engine directly, Podman users can run <code>podman compose up -d</code>, or force the wrapper to use Podman with <code>./compose.sh --engine podman up -d</code>.
Depending on your local Podman configuration, <code>podman compose</code> may still delegate to an external compose provider while talking to the Podman socket.</p>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">🐋 Standalone Deploy (Portainer, Uncloud, NAS, etc.)</h3><a id="user-content--standalone-deploy-portainer-uncloud-nas-etc" class="anchor" aria-label="Permalink: 🐋 Standalone Deploy (Portainer, Uncloud, NAS, etc.)" href="#-standalone-deploy-portainer-uncloud-nas-etc"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">No need to clone the repo. Use the pre-built images published to the GitHub Container Registry.</p>
<p dir="auto">Create a <code>docker-compose.yml</code> with the following content and deploy it directly — paste it into Portainer's stack editor, <code>uncloud deploy</code>, or any Docker host:</p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="services:
  backend:
    image: ghcr.io/bigbodycobain/shadowbroker-backend:latest
    container_name: shadowbroker-backend
    ports:
      - &quot;8000:8000&quot;
    environment:
      - AIS_API_KEY=your_aisstream_key          # Required — get one free at aisstream.io
      - OPENSKY_CLIENT_ID=                       # Optional — higher flight data rate limits
      - OPENSKY_CLIENT_SECRET=                   # Optional — paired with Client ID above
      - LTA_ACCOUNT_KEY=                         # Optional — Singapore CCTV cameras
      - CORS_ORIGINS=                            # Optional — comma-separated allowed origins
    volumes:
      - backend_data:/app/data
    restart: unless-stopped

  frontend:
    image: ghcr.io/bigbodycobain/shadowbroker-frontend:latest
    container_name: shadowbroker-frontend
    ports:
      - &quot;3000:3000&quot;
    environment:
      - BACKEND_URL=http://backend:8000   # Docker internal networking — no rebuild needed
    depends_on:
      - backend
    restart: unless-stopped

volumes:
  backend_data:"><pre><span class="pl-ent">services</span>:
  <span class="pl-ent">backend</span>:
    <span class="pl-ent">image</span>: <span class="pl-s">ghcr.io/bigbodycobain/shadowbroker-backend:latest</span>
    <span class="pl-ent">container_name</span>: <span class="pl-s">shadowbroker-backend</span>
    <span class="pl-ent">ports</span>:
      - <span class="pl-s"><span class="pl-pds">"</span>8000:8000<span class="pl-pds">"</span></span>
    <span class="pl-ent">environment</span>:
      - <span class="pl-s">AIS_API_KEY=your_aisstream_key          </span><span class="pl-c"><span class="pl-c">#</span> Required — get one free at aisstream.io</span>
      - <span class="pl-s">OPENSKY_CLIENT_ID=                       </span><span class="pl-c"><span class="pl-c">#</span> Optional — higher flight data rate limits</span>
      - <span class="pl-s">OPENSKY_CLIENT_SECRET=                   </span><span class="pl-c"><span class="pl-c">#</span> Optional — paired with Client ID above</span>
      - <span class="pl-s">LTA_ACCOUNT_KEY=                         </span><span class="pl-c"><span class="pl-c">#</span> Optional — Singapore CCTV cameras</span>
      - <span class="pl-s">CORS_ORIGINS=                            </span><span class="pl-c"><span class="pl-c">#</span> Optional — comma-separated allowed origins</span>
    <span class="pl-ent">volumes</span>:
      - <span class="pl-s">backend_data:/app/data</span>
    <span class="pl-ent">restart</span>: <span class="pl-s">unless-stopped</span>

  <span class="pl-ent">frontend</span>:
    <span class="pl-ent">image</span>: <span class="pl-s">ghcr.io/bigbodycobain/shadowbroker-frontend:latest</span>
    <span class="pl-ent">container_name</span>: <span class="pl-s">shadowbroker-frontend</span>
    <span class="pl-ent">ports</span>:
      - <span class="pl-s"><span class="pl-pds">"</span>3000:3000<span class="pl-pds">"</span></span>
    <span class="pl-ent">environment</span>:
      - <span class="pl-s">BACKEND_URL=http://backend:8000   </span><span class="pl-c"><span class="pl-c">#</span> Docker internal networking — no rebuild needed</span>
    <span class="pl-ent">depends_on</span>:
      - <span class="pl-s">backend</span>
    <span class="pl-ent">restart</span>: <span class="pl-s">unless-stopped</span>

<span class="pl-ent">volumes</span>:
  <span class="pl-ent">backend_data</span>:</pre></div>
<blockquote>
<p dir="auto"><strong>How it works:</strong> The frontend container proxies all <code>/api/*</code> requests through the Next.js server to <code>BACKEND_URL</code> using Docker's internal networking. The browser only ever talks to port 3000 — port 8000 does not need to be exposed externally.</p>
<p dir="auto"><code>BACKEND_URL</code> is a plain runtime environment variable (not a build-time <code>NEXT_PUBLIC_*</code>), so you can change it in Portainer, Uncloud, or any compose editor without rebuilding the image. Set it to the address where your backend is reachable from inside the Docker network (e.g. <code>http://backend:8000</code>, <code>http://192.168.1.50:8000</code>).</p>
</blockquote>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">📦 Quick Start (No Code Required)</h3><a id="user-content--quick-start-no-code-required" class="anchor" aria-label="Permalink: 📦 Quick Start (No Code Required)" href="#-quick-start-no-code-required"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you just want to run the dashboard without dealing with terminal commands:</p>
<ol dir="auto">
<li>Go to the <strong><a href="../../releases">Releases</a></strong> tab on the right side of this GitHub page.</li>
<li>Download the latest <code>.zip</code> file from the release.</li>
<li>Extract the folder to your computer.</li>
<li><strong>Windows:</strong> Double-click <code>start.bat</code>.
<strong>Mac/Linux:</strong> Open terminal, type <code>chmod +x start.sh</code>, and run <code>./start.sh</code>.</li>
<li>It will automatically install everything and launch the dashboard!</li>
</ol>
<hr>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">💻 Developer Setup</h3><a id="user-content--developer-setup" class="anchor" aria-label="Permalink: 💻 Developer Setup" href="#-developer-setup"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you want to modify the code or run from source:</p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Prerequisites</h4><a id="user-content-prerequisites" class="anchor" aria-label="Permalink: Prerequisites" href="#prerequisites"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Node.js</strong> 18+ and <strong>npm</strong> — <a href="https://nodejs.org/" rel="nofollow">nodejs.org</a></li>
<li><strong>Python</strong> 3.10, 3.11, or 3.12 with <code>pip</code> — <a href="https://www.python.org/downloads/" rel="nofollow">python.org</a> (<strong>check "Add to PATH"</strong> during install)
<ul dir="auto">
<li><g-emoji class="g-emoji" alias="warning">⚠️</g-emoji> Python 3.13+ may have compatibility issues with some dependencies. <strong>3.11 or 3.12 is recommended.</strong></li>
</ul>
</li>
<li>API keys for: <code>aisstream.io</code> (required), and optionally <code>opensky-network.org</code> (OAuth2), <code>lta.gov.sg</code></li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Installation</h3><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Clone the repository
git clone https://github.com/your-username/shadowbroker.git
cd shadowbroker/live-risk-dashboard

# Backend setup
cd backend
python -m venv venv
venv\Scripts\activate        # Windows
# source venv/bin/activate   # macOS/Linux
pip install -r requirements.txt   # includes pystac-client for Sentinel-2

# Create .env with your API keys
echo &quot;AIS_API_KEY=your_aisstream_key&quot; &gt;&gt; .env
echo &quot;OPENSKY_CLIENT_ID=your_opensky_client_id&quot; &gt;&gt; .env
echo &quot;OPENSKY_CLIENT_SECRET=your_opensky_secret&quot; &gt;&gt; .env

# Frontend setup
cd ../frontend
npm install"><pre><span class="pl-c"><span class="pl-c">#</span> Clone the repository</span>
git clone https://github.com/your-username/shadowbroker.git
<span class="pl-c1">cd</span> shadowbroker/live-risk-dashboard

<span class="pl-c"><span class="pl-c">#</span> Backend setup</span>
<span class="pl-c1">cd</span> backend
python -m venv venv
venv<span class="pl-cce">\S</span>cripts<span class="pl-cce">\a</span>ctivate        <span class="pl-c"><span class="pl-c">#</span> Windows</span>
<span class="pl-c"><span class="pl-c">#</span> source venv/bin/activate   # macOS/Linux</span>
pip install -r requirements.txt   <span class="pl-c"><span class="pl-c">#</span> includes pystac-client for Sentinel-2</span>

<span class="pl-c"><span class="pl-c">#</span> Create .env with your API keys</span>
<span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span>AIS_API_KEY=your_aisstream_key<span class="pl-pds">"</span></span> <span class="pl-k">&gt;&gt;</span> .env
<span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span>OPENSKY_CLIENT_ID=your_opensky_client_id<span class="pl-pds">"</span></span> <span class="pl-k">&gt;&gt;</span> .env
<span class="pl-c1">echo</span> <span class="pl-s"><span class="pl-pds">"</span>OPENSKY_CLIENT_SECRET=your_opensky_secret<span class="pl-pds">"</span></span> <span class="pl-k">&gt;&gt;</span> .env

<span class="pl-c"><span class="pl-c">#</span> Frontend setup</span>
<span class="pl-c1">cd</span> ../frontend
npm install</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Running</h3><a id="user-content-running" class="anchor" aria-label="Permalink: Running" href="#running"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# From the frontend directory — starts both frontend &amp; backend concurrently
npm run dev"><pre><span class="pl-c"><span class="pl-c">#</span> From the frontend directory — starts both frontend &amp; backend concurrently</span>
npm run dev</pre></div>
<p dir="auto">This starts:</p>
<ul dir="auto">
<li><strong>Next.js</strong> frontend on <code>http://localhost:3000</code></li>
<li><strong>FastAPI</strong> backend on <code>http://localhost:8000</code></li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🎛️ Data Layers</h2><a id="user-content-️-data-layers" class="anchor" aria-label="Permalink: 🎛️ Data Layers" href="#️-data-layers"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">All layers are independently toggleable from the left panel:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Layer</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Commercial Flights</td>
<td>✅ ON</td>
<td>Airlines, cargo, GA aircraft</td>
</tr>
<tr>
<td>Private Flights</td>
<td>✅ ON</td>
<td>Non-commercial private aircraft</td>
</tr>
<tr>
<td>Private Jets</td>
<td>✅ ON</td>
<td>High-value bizjets with owner data</td>
</tr>
<tr>
<td>Military Flights</td>
<td>✅ ON</td>
<td>Military &amp; government aircraft</td>
</tr>
<tr>
<td>Tracked Aircraft</td>
<td>✅ ON</td>
<td>Special interest watch list</td>
</tr>
<tr>
<td>Satellites</td>
<td>✅ ON</td>
<td>Orbital assets by mission type</td>
</tr>
<tr>
<td>Carriers / Mil / Cargo</td>
<td>✅ ON</td>
<td>Navy carriers, cargo ships, tankers</td>
</tr>
<tr>
<td>Civilian Vessels</td>
<td>❌ OFF</td>
<td>Yachts, fishing, recreational</td>
</tr>
<tr>
<td>Cruise / Passenger</td>
<td>✅ ON</td>
<td>Cruise ships and ferries</td>
</tr>
<tr>
<td>Earthquakes (24h)</td>
<td>✅ ON</td>
<td>USGS seismic events</td>
</tr>
<tr>
<td>CCTV Mesh</td>
<td>❌ OFF</td>
<td>Surveillance camera network</td>
</tr>
<tr>
<td>Ukraine Frontline</td>
<td>✅ ON</td>
<td>Live warfront positions</td>
</tr>
<tr>
<td>Global Incidents</td>
<td>✅ ON</td>
<td>GDELT conflict events</td>
</tr>
<tr>
<td>GPS Jamming</td>
<td>✅ ON</td>
<td>NAC-P degradation zones</td>
</tr>
<tr>
<td>MODIS Terra (Daily)</td>
<td>❌ OFF</td>
<td>NASA GIBS daily satellite imagery</td>
</tr>
<tr>
<td>High-Res Satellite</td>
<td>❌ OFF</td>
<td>Esri sub-meter satellite imagery</td>
</tr>
<tr>
<td>KiwiSDR Receivers</td>
<td>❌ OFF</td>
<td>Public SDR radio receivers</td>
</tr>
<tr>
<td>Fire Hotspots (24h)</td>
<td>❌ OFF</td>
<td>NASA FIRMS VIIRS thermal anomalies</td>
</tr>
<tr>
<td>Internet Outages</td>
<td>❌ OFF</td>
<td>IODA regional connectivity alerts</td>
</tr>
<tr>
<td>Data Centers</td>
<td>❌ OFF</td>
<td>Global data center locations (2,000+)</td>
</tr>
<tr>
<td>Day / Night Cycle</td>
<td>✅ ON</td>
<td>Solar terminator overlay</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🔧 Performance</h2><a id="user-content--performance" class="anchor" aria-label="Permalink: 🔧 Performance" href="#-performance"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The platform is optimized for handling massive real-time datasets:</p>
<ul dir="auto">
<li><strong>Gzip Compression</strong> — API payloads compressed ~92% (11.6 MB → 915 KB)</li>
<li><strong>ETag Caching</strong> — <code>304 Not Modified</code> responses skip redundant JSON parsing</li>
<li><strong>Viewport Culling</strong> — Only features within the visible map bounds (+20% buffer) are rendered</li>
<li><strong>Imperative Map Updates</strong> — High-volume layers (flights, satellites, fires) bypass React reconciliation via direct <code>setData()</code> calls</li>
<li><strong>Clustered Rendering</strong> — Ships, CCTV, earthquakes, and data centers use MapLibre clustering to reduce feature count</li>
<li><strong>Debounced Viewport Updates</strong> — 300ms debounce prevents GeoJSON rebuild thrash during pan/zoom; 2s debounce on dense layers (satellites, fires)</li>
<li><strong>Position Interpolation</strong> — Smooth 10s tick animation between data refreshes</li>
<li><strong>React.memo</strong> — Heavy components wrapped to prevent unnecessary re-renders</li>
<li><strong>Coordinate Precision</strong> — Lat/lng rounded to 5 decimals (~1m) to reduce JSON size</li>
</ul>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📁 Project Structure</h2><a id="user-content--project-structure" class="anchor" aria-label="Permalink: 📁 Project Structure" href="#-project-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="live-risk-dashboard/
├── backend/
│   ├── main.py                     # FastAPI app, middleware, API routes
│   ├── carrier_cache.json          # Persisted carrier OSINT positions
│   ├── cctv.db                     # SQLite CCTV camera database
│   ├── config/
│   │   └── news_feeds.json         # User-customizable RSS feed list (persists across restarts)
│   └── services/
│       ├── data_fetcher.py         # Core scheduler — fetches all data sources
│       ├── ais_stream.py           # AIS WebSocket client (25K+ vessels)
│       ├── carrier_tracker.py      # OSINT carrier position tracker
│       ├── cctv_pipeline.py        # Multi-source CCTV camera ingestion
│       ├── geopolitics.py          # GDELT + Ukraine frontline fetcher
│       ├── region_dossier.py       # Right-click country/city intelligence
│       ├── radio_intercept.py      # Scanner radio feed integration
│       ├── kiwisdr_fetcher.py      # KiwiSDR receiver scraper
│       ├── sentinel_search.py      # Sentinel-2 STAC imagery search
│       ├── network_utils.py        # HTTP client with curl fallback
│       ├── api_settings.py         # API key management
│       └── news_feed_config.py     # RSS feed config manager (add/remove/weight feeds)
│
├── frontend/
│   ├── src/
│   │   ├── app/
│   │   │   └── page.tsx            # Main dashboard — state, polling, layout
│   │   └── components/
│   │       ├── MaplibreViewer.tsx   # Core map — 2,000+ lines, all GeoJSON layers
│   │       ├── NewsFeed.tsx         # SIGINT feed + entity detail panels
│   │       ├── WorldviewLeftPanel.tsx   # Data layer toggles
│   │       ├── WorldviewRightPanel.tsx  # Search + filter sidebar
│   │       ├── FilterPanel.tsx     # Basic layer filters
│   │       ├── AdvancedFilterModal.tsx  # Airport/country/owner filtering
│   │       ├── MapLegend.tsx       # Dynamic legend with all icons
│   │       ├── MarketsPanel.tsx    # Global financial markets ticker
│   │       ├── RadioInterceptPanel.tsx # Scanner-style radio panel
│   │       ├── FindLocateBar.tsx   # Search/locate bar
│   │       ├── ChangelogModal.tsx  # Version changelog popup
│   │       ├── SettingsPanel.tsx   # App settings (API Keys + News Feed manager)
│   │       ├── ScaleBar.tsx        # Map scale indicator
│   │       ├── WikiImage.tsx       # Wikipedia image fetcher
│   │       └── ErrorBoundary.tsx   # Crash recovery wrapper
│   └── package.json"><pre class="notranslate"><code>live-risk-dashboard/
├── backend/
│   ├── main.py                     # FastAPI app, middleware, API routes
│   ├── carrier_cache.json          # Persisted carrier OSINT positions
│   ├── cctv.db                     # SQLite CCTV camera database
│   ├── config/
│   │   └── news_feeds.json         # User-customizable RSS feed list (persists across restarts)
│   └── services/
│       ├── data_fetcher.py         # Core scheduler — fetches all data sources
│       ├── ais_stream.py           # AIS WebSocket client (25K+ vessels)
│       ├── carrier_tracker.py      # OSINT carrier position tracker
│       ├── cctv_pipeline.py        # Multi-source CCTV camera ingestion
│       ├── geopolitics.py          # GDELT + Ukraine frontline fetcher
│       ├── region_dossier.py       # Right-click country/city intelligence
│       ├── radio_intercept.py      # Scanner radio feed integration
│       ├── kiwisdr_fetcher.py      # KiwiSDR receiver scraper
│       ├── sentinel_search.py      # Sentinel-2 STAC imagery search
│       ├── network_utils.py        # HTTP client with curl fallback
│       ├── api_settings.py         # API key management
│       └── news_feed_config.py     # RSS feed config manager (add/remove/weight feeds)
│
├── frontend/
│   ├── src/
│   │   ├── app/
│   │   │   └── page.tsx            # Main dashboard — state, polling, layout
│   │   └── components/
│   │       ├── MaplibreViewer.tsx   # Core map — 2,000+ lines, all GeoJSON layers
│   │       ├── NewsFeed.tsx         # SIGINT feed + entity detail panels
│   │       ├── WorldviewLeftPanel.tsx   # Data layer toggles
│   │       ├── WorldviewRightPanel.tsx  # Search + filter sidebar
│   │       ├── FilterPanel.tsx     # Basic layer filters
│   │       ├── AdvancedFilterModal.tsx  # Airport/country/owner filtering
│   │       ├── MapLegend.tsx       # Dynamic legend with all icons
│   │       ├── MarketsPanel.tsx    # Global financial markets ticker
│   │       ├── RadioInterceptPanel.tsx # Scanner-style radio panel
│   │       ├── FindLocateBar.tsx   # Search/locate bar
│   │       ├── ChangelogModal.tsx  # Version changelog popup
│   │       ├── SettingsPanel.tsx   # App settings (API Keys + News Feed manager)
│   │       ├── ScaleBar.tsx        # Map scale indicator
│   │       ├── WikiImage.tsx       # Wikipedia image fetcher
│   │       └── ErrorBoundary.tsx   # Crash recovery wrapper
│   └── package.json
</code></pre></div>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">🔑 Environment Variables</h2><a id="user-content--environment-variables" class="anchor" aria-label="Permalink: 🔑 Environment Variables" href="#-environment-variables"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Backend (<code>backend/.env</code>)</h3><a id="user-content-backend-backendenv" class="anchor" aria-label="Permalink: Backend (backend/.env)" href="#backend-backendenv"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-dotenv notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Required
AIS_API_KEY=your_aisstream_key                # Maritime vessel tracking (aisstream.io)

# Optional (enhances data quality)
OPENSKY_CLIENT_ID=your_opensky_client_id      # OAuth2 — higher rate limits for flight data
OPENSKY_CLIENT_SECRET=your_opensky_secret     # OAuth2 — paired with Client ID above
LTA_ACCOUNT_KEY=your_lta_key                  # Singapore CCTV cameras"><pre><span class="pl-c"><span class="pl-c">#</span> Required</span>
<span class="pl-v">AIS_API_KEY</span><span class="pl-k">=</span><span class="pl-s">your_aisstream_key</span>                <span class="pl-c"><span class="pl-c">#</span> Maritime vessel tracking (aisstream.io)</span>

<span class="pl-c"><span class="pl-c">#</span> Optional (enhances data quality)</span>
<span class="pl-v">OPENSKY_CLIENT_ID</span><span class="pl-k">=</span><span class="pl-s">your_opensky_client_id</span>      <span class="pl-c"><span class="pl-c">#</span> OAuth2 — higher rate limits for flight data</span>
<span class="pl-v">OPENSKY_CLIENT_SECRET</span><span class="pl-k">=</span><span class="pl-s">your_opensky_secret</span>     <span class="pl-c"><span class="pl-c">#</span> OAuth2 — paired with Client ID above</span>
<span class="pl-v">LTA_ACCOUNT_KEY</span><span class="pl-k">=</span><span class="pl-s">your_lta_key</span>                  <span class="pl-c"><span class="pl-c">#</span> Singapore CCTV cameras</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Frontend</h3><a id="user-content-frontend" class="anchor" aria-label="Permalink: Frontend" href="#frontend"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Variable</th>
<th>Where to set</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>BACKEND_URL</code></td>
<td><code>environment</code> in <code>docker-compose.yml</code>, or shell env</td>
<td>URL the Next.js server uses to proxy API calls to the backend. Defaults to <code>http://backend:8000</code>. <strong>Runtime variable — no rebuild needed.</strong></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto"><strong>How it works:</strong> The frontend proxies all <code>/api/*</code> requests through the Next.js server to <code>BACKEND_URL</code> using Docker's internal networking. Browsers only talk to port 3000; port 8000 never needs to be exposed externally. For local dev without Docker, <code>BACKEND_URL</code> defaults to <code>http://localhost:8000</code>.</p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto"><g-emoji class="g-emoji" alias="warning">⚠️</g-emoji> Disclaimer</h2><a id="user-content-️-disclaimer" class="anchor" aria-label="Permalink: ⚠️ Disclaimer" href="#️-disclaimer"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This is an <strong>educational and research tool</strong> built entirely on publicly available, open-source intelligence (OSINT) data. No classified, restricted, or non-public data sources are used. Carrier positions are estimates based on public reporting. The military-themed UI is purely aesthetic.</p>
<p dir="auto"><strong>Do not use this tool for any operational, military, or intelligence purpose.</strong></p>
<hr>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">📜 License</h2><a id="user-content--license" class="anchor" aria-label="Permalink: 📜 License" href="#-license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This project is for educational and personal research purposes. See individual API provider terms of service for data usage restrictions.</p>
<hr>
<p align="center" dir="auto">
  <sub>Built with ☕ and too many API calls</sub>
</p>
</article></div>]]></description>
      <link>https://github.com/BigBodyCobain/Shadowbroker</link>
      <guid>https://github.com/BigBodyCobain/Shadowbroker</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Code Review for Claude Code]]></title>
      <description><![CDATA[Code Review for Claude Code | Claude<noscript>
</noscript>
<div class="page_wrap"><div class="u-position-fixed">`;
      document.body.appendChild(el);
      return el;
    }
    const bubble  = ensureBubble();
    const elH     = bubble.querySelector("#tt-title");
    const elB     = bubble.querySelector("#tt-body");
    const elClose = bubble.querySelector(".tt-close");
    // ---------------- Parse [[term|heading|body]] anywhere ----------------
    const TOKEN_RE = /\[\[([^|\]]+)\|([^|\]]+)\|([^\]]+)\]\]/g;
    const BLOCK_SKIP = new Set(["SCRIPT","STYLE","NOSCRIPT","TEXTAREA","INPUT","SELECT","CODE","PRE","TEMPLATE","IFRAME"]);
    function shouldSkipTextNode(n){
      let el = n.parentElement;
      while (el){
        if (BLOCK_SKIP.has(el.tagName) || el.isContentEditable) return true;
        el = el.parentElement;
      }
      return false;
    }
    const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
    const textNodes = [];
    while (walker.nextNode()){
      const n = walker.currentNode;
      if (!n.nodeValue || shouldSkipTextNode(n)) continue;
      if (TOKEN_RE.test(n.nodeValue)) textNodes.push(n);
      TOKEN_RE.lastIndex = 0;
    }
    textNodes.forEach(node =&gt; {
      const frag = document.createDocumentFragment();
      const insideLink = !!node.parentElement.closest("a");
      let text = node.nodeValue, last = 0; TOKEN_RE.lastIndex = 0; let m;
      while ((m = TOKEN_RE.exec(text))){
        if (m.index &gt; last) frag.appendChild(document.createTextNode(text.slice(last, m.index)));
        const term=m[1].trim(), heading=m[2].trim(), body=m[3].trim();
        const t = insideLink ? document.createElement("span") : document.createElement("button");
        if (insideLink){ t.setAttribute("role","button"); t.setAttribute("tabindex","0"); } else { t.type="button"; }
        t.className="tt-trigger";
        t.textContent=term;
        t.setAttribute("data-tt-h", heading);
        t.setAttribute("data-tt-b", body);
        t.setAttribute("aria-haspopup","dialog");
        t.setAttribute("aria-expanded","false");
        frag.appendChild(t);
        last = TOKEN_RE.lastIndex;
      }
      if (last &lt; text.length) frag.appendChild(document.createTextNode(text.slice(last)));
      node.parentNode.replaceChild(frag, node);
    });
    // ---------------- State ----------------
    let current = null;
    let hoverCount = 0;
    let closeTimer = null;
    // Dimming bookkeeping
    let dimCtx = null; // { container, dimEls:[], wrappedTexts:[], pathEls:[] }
    // ---------------- Find the correct "text element" container ----------------
    function findTextContainer(trigger){
      // Prefer common RTE wrappers
      let el = trigger.closest(".w-richtext, .rich-text, .rte, [data-rte]");
      if (el) return el;
      // Otherwise climb until we find an ancestor that contains multiple block nodes anywhere inside.
      const BLOCK_SEL = "p,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,pre,figure,figcaption";
      el = trigger.parentElement;
      while (el &amp;&amp; el !== document.body){
        const blockCount = el.querySelectorAll(BLOCK_SEL).length;
        if (blockCount &gt;= 2) return el;
        el = el.parentElement;
      }
      // Fallback: nearest non-inline container
      el = trigger.parentElement || document.body;
      while (el &amp;&amp; el !== document.body){
        const d = getComputedStyle(el).display;
        if (d !== "inline" &amp;&amp; d !== "contents") return el;
        el = el.parentElement;
      }
      return document.body;
    }
    // Utility: child of `ancestor` that contains `target` (direct child)
    function directChildContaining(ancestor, target){
      for (const ch of ancestor.children){
        if (ch === target || ch.contains(target)) return ch;
      }
      return null;
    }
    function getElementTarget(e) {
    // If target is already an Element, use it
    if (e.target instanceof Element) return e.target;
    // Otherwise, walk the composed/path for the first Element
    const path = (typeof e.composedPath === 'function') ? e.composedPath() : [];
    for (const n of path) if (n instanceof Element) return n;
    return null;
  }
    // ---------------- Dim everything except the trigger branch (sibling branches only) ----------------
    function dimAllOtherBranches(container, trigger){
      undim(); // clear previous
      const dimEls = [];
      const wrappedTexts = [];
      const pathEls = [];
      // Build ELEMENT-only path [container -&gt; ... -&gt; trigger]
      const path = [];
      for (let el = trigger; el &amp;&amp; el !== container; el = el.parentElement) path.push(el);
      path.push(container);
      path.reverse();
      // At each ancestor level, find the *direct* child that leads to the trigger
      for (let i = 0; i &lt; path.length; i++){
        const anc = path[i];
        const branchChild = (i &lt; path.length - 1) ? directChildContaining(anc, path[i+1]) : path[i]; // last step is the trigger itself
        // Fade element siblings (whole branches)
        for (const child of anc.children){
          if (child === branchChild) continue; // keep the path branch crisp
          // Never fade any element that is (or contains) the trigger
          if (child === trigger || child.contains(trigger)) continue;
          child.style.transition = `opacity ${DIM_EASE_MS}ms ease`;
          child.style.opacity = String(DIM_OPACITY);
          dimEls.push(child);
        }
        // Fade TEXT NODE siblings directly under this ancestor (outside branchChild)
        anc.childNodes.forEach(node =&gt; {
          if (node.nodeType !== 3) return; // text only
          if (!node.nodeValue || !node.nodeValue.trim()) return;
          // If this text node sits inside branchChild, skip
          if (branchChild &amp;&amp; branchChild.contains &amp;&amp; branchChild.contains(node)) return;
          const span = document.createElement("span");
          span.style.transition = `opacity ${DIM_EASE_MS}ms ease`;
          span.style.opacity = String(DIM_OPACITY);
          span.textContent = node.nodeValue;
          node.parentNode.replaceChild(span, node);
          wrappedTexts.push(span);
        });
        // Keep a reference to the path elements (so we can explicitly restore opacity if needed)
        if (anc &amp;&amp; anc.nodeType === 1) pathEls.push(anc);
      }
      // Hard-guard: explicitly set opacity:1 on the entire path to neutralize any inherited fade
      pathEls.forEach(el =&gt; {
        el.style.opacity = "1";
      });
      dimCtx = { container, dimEls, wrappedTexts, pathEls };
    }
    function undim(){
      if (!dimCtx) return;
      const { dimEls, wrappedTexts, pathEls } = dimCtx;
      // Animate back
      dimEls.forEach(el =&gt; {
        el.style.transition = `opacity ${DIM_EASE_MS}ms ease`;
        el.style.opacity = "1";
        // remove inline style after the animation so we don't override site CSS
        setTimeout(() =&gt; { if (el) el.style.opacity = ""; }, DIM_EASE_MS + 50);
      });
      wrappedTexts.forEach(span =&gt; {
        span.style.transition = `opacity ${DIM_EASE_MS}ms ease`;
        span.style.opacity = "1";
        span.addEventListener("transitionend", () =&gt; {
          if (!span.parentNode) return;
          span.parentNode.replaceChild(document.createTextNode(span.textContent || ""), span);
        }, { once:true });
      });
      // Clear hard-guard on path
      pathEls.forEach(el =&gt; { if (el) el.style.opacity = ""; });
      dimCtx = null;
    }
    // ---------------- Positioning (centered, edge-aware, flip) ----------------
    function clamp(v,min,max){ return Math.max(min,Math.min(max,v)); }
    function measureBubbleForPlacement(){
      const wasOpen = bubble.classList.contains("is-open");
      if (!wasOpen){ bubble.style.visibility="hidden"; bubble.classList.add("is-open"); }
      const rect = bubble.getBoundingClientRect();
      if (!wasOpen){ bubble.classList.remove("is-open"); bubble.style.visibility=""; }
      return { w: rect.width, h: rect.height };
    }
    function placeAnchored(trigger){
      const vw=innerWidth, vh=innerHeight;
      const r = trigger.getBoundingClientRect();
      const { w, h } = measureBubbleForPlacement();
      let left = r.left + (r.width/2) - (w/2);
      left = clamp(left, EDGE_PADDING, Math.max(EDGE_PADDING, vw - EDGE_PADDING - w));
      const topBelow   = r.bottom + OFFSET_Y;
      const spaceBelow = vh - topBelow - EDGE_PADDING;
      const placeBelow = spaceBelow &gt;= h;
      let top = placeBelow ? topBelow : (r.top - h - OFFSET_Y);
      top = clamp(top, EDGE_PADDING, Math.max(EDGE_PADDING, vh - EDGE_PADDING - h));
      bubble.style.left = left + "px";
      bubble.style.top  = top  + "px";
      const br = bubble.getBoundingClientRect();
      if (br.bottom &gt; vh - EDGE_PADDING){
        bubble.style.maxHeight = (vh - 2*EDGE_PADDING) + "px";
        bubble.style.overflowY = "auto";
      } else {
        bubble.style.maxHeight = "none";
        bubble.style.overflowY = "visible";
      }
    }
    // ---------------- Open / Close (place → fade/scale) ----------------
    function animateIn(){
      bubble.style.transition = "none";
      bubble.style.opacity = "0";
      bubble.style.transform = "scale(0.95)";
      void bubble.offsetWidth;
      bubble.style.transition = "opacity .18s ease, transform .18s ease";
      bubble.style.opacity = "1";
      bubble.style.transform = "scale(1)";
    }
    function animateOut(done){
      bubble.style.transition = "opacity .16s ease, transform .16s ease";
      bubble.style.opacity = "0";
      bubble.style.transform = "scale(0.95)";
      const end = () =&gt; { bubble.removeEventListener("transitionend", end); done &amp;&amp; done(); };
      bubble.addEventListener("transitionend", end);
      setTimeout(end, 260);
    }
    function openFromTrigger(trigger){
      if (current &amp;&amp; current !== trigger) forceClose();
      current = trigger;
      trigger.setAttribute("aria-expanded","true");
      elH.textContent = trigger.getAttribute("data-tt-h") || "";
      elB.textContent = trigger.getAttribute("data-tt-b") || "";
      bubble.classList.add("is-open");
      bubble.setAttribute("aria-hidden","false");
      placeAnchored(trigger);
      animateIn();
      const container = findTextContainer(trigger);
      dimAllOtherBranches(container, trigger);
      hoverCount = 0;
      cancelCloseTimer();
    }
    function forceClose(){
      if (!current) return;
      bubble.classList.remove("is-open");
      bubble.setAttribute("aria-hidden","true");
      current.setAttribute("aria-expanded","false");
      current = null;
      undim();
      hoverCount = 0;
      cancelCloseTimer();
    }
    function closeWithAnim(){
      if (!current) return;
      const t = current;
      animateOut(() =&gt; {
        bubble.classList.remove("is-open");
        bubble.setAttribute("aria-hidden","true");
        t.setAttribute("aria-expanded","false");
        current = null;
        undim();
      });
    }
    function scheduleClose(){
      cancelCloseTimer();
      closeTimer = setTimeout(() =&gt; {
        if (hoverCount &lt;= 0 &amp;&amp; !isCoarse()) closeWithAnim();
      }, CLOSE_DELAY);
    }
    function cancelCloseTimer(){ if (closeTimer){ clearTimeout(closeTimer); closeTimer = null; } }
    // ---------------- Hover-intent (desktop) ----------------
    function onZoneEnter(){ if (isCoarse()) return; hoverCount++; cancelCloseTimer(); }
    function onZoneLeave(){ if (isCoarse()) return; hoverCount = Math.max(0, hoverCount - 1); if (hoverCount === 0) scheduleClose(); }
    bubble.addEventListener("pointerenter", onZoneEnter, true);
    bubble.addEventListener("mouseenter",   onZoneEnter, true);
    bubble.addEventListener("pointerleave", onZoneLeave, true);
    bubble.addEventListener("mouseleave",   onZoneLeave, true);
    const handleEnter = (e) =&gt; {
      if (isCoarse()) return;
      const target = getElementTarget(e);
      if (!target) return;
      const t = target.closest(".tt-trigger");
      if (!t) return;
      onZoneEnter();
      if (!current || current !== t) openFromTrigger(t);
    };
    const handleLeave = (e) =&gt; {
      if (isCoarse()) return;
      const target = getElementTarget(e);
      if (!target) return;
      const t = target.closest(".tt-trigger");
      if (!t) return;
      onZoneLeave();
    };
    document.addEventListener("pointerenter", handleEnter, true);
    document.addEventListener("mouseenter",   handleEnter, true);
    document.addEventListener("pointerleave", handleLeave, true);
    document.addEventListener("mouseleave",   handleLeave, true);
    // ---------------- Keyboard ----------------
    document.addEventListener("focusin", (e) =&gt; {
      if (!e.target) return;
      const t = e.target.closest(".tt-trigger");
      if (t) openFromTrigger(t);
    });
    document.addEventListener("focusout", (e) =&gt; {
      if (!e.target) return;
      const t = e.target.closest(".tt-trigger");
      if (t &amp;&amp; current === t) closeWithAnim();
    });
    // ---------------- Mobile / coarse ----------------
    document.addEventListener("pointerdown", (e) =&gt; {
      if (!isCoarse()) return;
      const t = e.target.closest(".tt-trigger");
      if (!t) return;
      e.preventDefault();
      e.stopPropagation();
      if (current === t &amp;&amp; bubble.classList.contains("is-open")) { closeWithAnim(); return; }
      openFromTrigger(t);
    }, true);
    document.addEventListener("click", (e) =&gt; {
      if (!isCoarse()) return;
      if (!bubble.classList.contains("is-open")) return;
      const inBubble  = !!e.target.closest(".tt-bubble");
      const onTrigger = !!e.target.closest(".tt-trigger");
      if (!inBubble &amp;&amp; !onTrigger) closeWithAnim();
    }, true);
    // Close button + ESC
    elClose.addEventListener("click", closeWithAnim);
    document.addEventListener("keydown", (e) =&gt; { if (e.key === "Escape") closeWithAnim(); });
    // Reposition on resize/scroll while open
    const reposition = () =&gt; { if (!current) return; placeAnchored(current); };
    addEventListener("resize", reposition, { passive: true });
    addEventListener("scroll", reposition, { passive: true });
  });
]]&gt;</div></div>
<main id="main" class="page_main"><section data-prevent-flicker="true" data-animate-hero-wrap="" class="hero_blog_post_wrap u-section"><div class="hero_blog_post_contain u-container u-threshold-medium hero_blog_post_layout u-grid-custom"><div id="w-node-_512c3258-1b20-382a-88d4-7eab7cbdc3f9-b08de180" class="hero_blog_post_content u-column-custom hero_stories_heading_wrap"><div data-illustration-bg="Clay" class="hero_blog_post_illo_wrap"><img src="https://cdn.prod.website-files.com/68a44d4040f98a4adf2207b6/692f76874e94e489958af8ba_Object-CodeMagnifier.svg" alt="" class="hero_blog_post_illo_img" /></div><div data-animate-hero-text="" class="hero_blog_description_wrap c-paragraph w-variant-a8a1af09-b22b-0ee5-ee77-23c3e377a779 u-text-wrap-pretty w-richtext u-rich-text u-max-width-60ch u-mt-2"><p><em>Claude Code now has a thorough, agent team-based review system, modeled on the one we run at Anthropic. Available in research preview.</em></p></div></div><div id="w-node-_512c3258-1b20-382a-88d4-7eab7cbdc3ec-b08de180" class="hero_blog_post_details u-column-custom"><ul role="list" class="hero_blog_post_details_list"><li class="hero_blog_post_details_item u-hide-if-empty-cms">
<div class="hero_blog_post_details_content"><p>Category</p></div>
</li>
<li class="hero_blog_post_details_item u-hide-if-empty-cms">
<div class="hero_blog_post_details_content"><p>Product</p><p>Claude Code</p></div>
</li>
<li class="hero_blog_post_details_item">
<div class="hero_blog_post_details_content"><p>Date</p><p>March 9, 2026</p></div>
</li>
<li class="hero_blog_post_details_item">
<div class="hero_blog_post_details_content"><p>Reading time</p></div>
</li>
<li class="hero_blog_post_details_item">
<div class="hero_blog_post_details_content"><p>Share</p><a data-wf-native-id-path="c328f618-c410-4c26-ebfd-504346b59662" data-wf-ao-click-engagement-tracking="true" data-wf-element-id="c328f618-c410-4c26-ebfd-504346b59662" href="#" class="u-rich-text u-text-style-body-3">Copy link</a><p>https://claude.com/blog/code-review</p></div>
</li>
</ul></div></div></section><section id="customer-stories" class="blog_post_section_wrap u-section"><div class="blog_post_contain u-container blog_post_component blog_post_wrap u-grid-custom"><div class="blog_post_layout u-column-custom blog_post_content_wrap u-rich-text-blog u-margin-trim w-richtext"><p>Today we're introducing Code Review, which dispatches a team of agents on every PR to catch the bugs that skims miss, built for depth, not speed. It's the system we run on nearly every PR at Anthropic. Now in research preview for Team and Enterprise.</p><figure class="w-richtext-align-fullwidth w-richtext-figure-type-video c1"><iframe src="https://www.youtube.com/embed/RKsADl0ZC3Y" title="Introducing Code Review" scrolling="no" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>
</figure><h2><strong>Managing the review bottleneck</strong></h2><p>Code output per Anthropic engineer has grown 200% in the last year. Code review has become a bottleneck, and we hear the same from customers every week. They tell us developers are stretched thin, and many PRs get skims rather than deep reads.</p><p>We needed a reviewer we could trust on every PR. Code Review is the result: deep, multi-agent reviews that catch bugs human reviewers often miss themselves. It's a more thorough (and more expensive) option than our existing <a href="https://code.claude.com/docs/en/github-actions" data-wf-native-id-path="cd3d040c-699f-7b1d-2d1f-b0efa4f36098" data-wf-ao-click-engagement-tracking="true" data-wf-element-id="cd3d040c-699f-7b1d-2d1f-b0efa4f36098">Claude Code GitHub Action</a>, which remains open source and available.</p><p>We run Code Review on nearly every PR at Anthropic. Before, 16% of PRs got substantive review comments. Now 54% do. It won't approve PRs — that's still a human call — but it closes the gap so reviewers can actually cover what's shipping.</p><h2><strong>How it works</strong></h2><p>When a PR is opened, Code Review dispatches a team of agents. The agents look for bugs in parallel, verify bugs to filter out false positives, and rank bugs by severity. The result lands on the PR as a single high-signal overview comment, plus in-line comments for specific bugs.</p><p>Reviews scale with the PR. Large or complex changes get more agents and a deeper read; trivial ones get a lightweight pass. Based on our testing, the average review takes around 20 minutes.</p><h2><strong>Code Review in action</strong></h2><p>We've been running Code Review internally for months: on large PRs (over 1,000 lines changed), 84% get findings, averaging 7.5 issues. On small PRs under 50 lines, that drops to 31%, averaging 0.5 issues. Engineers largely agree with what it surfaces: less than 1% of findings are marked incorrect.</p><p>In one case, a one-line change to a production service looked routine and was the kind of diff that normally gets a quick approval. But Code Review flagged it as critical. The change would have broken authentication for the service, a failure mode that’s easy to read past in the diff but obvious once pointed out. It was fixed before merge, and the engineer shared afterwards that they wouldn't have caught it on their own.</p><p>Early access customers have seen similar patterns. On a <a href="https://github.com/truenas/middleware/pull/18291" data-wf-native-id-path="cd3d040c-699f-7b1d-2d1f-b0efa4f360ad" data-wf-ao-click-engagement-tracking="true" data-wf-element-id="cd3d040c-699f-7b1d-2d1f-b0efa4f360ad">ZFS encryption refactor in TrueNAS's open-source middleware</a>, Code Review surfaced a pre-existing bug in adjacent code: a type mismatch that was silently wiping the encryption key cache on every sync. It was a latent issue in code the PR happened to touch, the kind of thing a human reviewer scanning the changeset wouldn't immediately go looking for.</p><h2><strong>Cost and control</strong></h2><p>Code Review optimizes for depth and is more expensive than lighter-weight solutions like the <a href="https://code.claude.com/docs/en/github-actions" data-wf-native-id-path="cd3d040c-699f-7b1d-2d1f-b0efa4f360b5" data-wf-ao-click-engagement-tracking="true" data-wf-element-id="cd3d040c-699f-7b1d-2d1f-b0efa4f360b5">Claude Code GitHub Action</a>. Reviews are billed on token usage and generally average $15–25, scaling with PR size and complexity. </p><p>Admins have many ways to control spend and usage:</p><ul role="list"><li><strong>Monthly organization caps</strong>: Define total monthly spend across all reviews</li>
<li><strong>Repository-level control</strong>: Enable reviews only on the repositories you choose</li>
<li><strong>Analytics dashboard</strong>: Track PRs reviewed, acceptance rate, and total review costs </li>
</ul><h2><strong>Getting started</strong></h2><p>Code Review is available now as a research preview in beta for Team and Enterprise plans. </p><ul role="list"><li><strong>For admins</strong>: Enable Code Review in your <a href="http://claude.ai/admin-settings/claude-code" data-wf-native-id-path="cd3d040c-699f-7b1d-2d1f-b0efa4f360f4" data-wf-ao-click-engagement-tracking="true" data-wf-element-id="cd3d040c-699f-7b1d-2d1f-b0efa4f360f4">Claude Code settings</a>, install the GitHub App, and select repositories you’d like to run reviews on.</li>
<li><strong>For developers</strong>: Once enabled, reviews run automatically on new PRs. No configuration needed.</li>
</ul><p><a href="http://code.claude.com/docs/en/code-review" data-wf-native-id-path="cd3d040c-699f-7b1d-2d1f-b0efa4f360de" data-wf-ao-click-engagement-tracking="true" data-wf-element-id="cd3d040c-699f-7b1d-2d1f-b0efa4f360de">Explore the docs</a> for more information.</p></div><div class="blog_post_layout u-column-custom is_testimonials w-condition-invisible slider_component"><p>No items found.</p></div></div></section><section class="blog_related_section_wrap u-section u-background-secondary u-hide-if-empty-cms"><div class="section_contain u-container"><div class="w-dyn-list blog_cms_grid u-grid-custom is_related_posts w-dyn-items"><div role="listitem" class="blog_cms_item w-dyn-item card_blog_wrap"><div class="card_blog_visual_wrap card_blog_visual card_blog_hero"><img src="https://cdn.prod.website-files.com/68a44d4040f98a4adf2207b6/6903d224f466b800c4a5a016_a7b8978859371a024139418f3366bb0600ee1675-1000x1000.svg" alt="" class="card_blog_illo" /></div><div class="card_blog_content"><div class="u-height-full"><p>Mar 12, 2026</p><h3 class="card_blog_title u-text-style-h6">Claude now creates interactive charts, diagrams and visualizations</h3></div><div class="w-dyn-list w-dyn-items u-foreground-tertiary w-dyn-item card-main_tag-wrap"><p>Product announcements</p></div></div><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%228dae13c3-f4de-fbf4-c16a-42833b2e96f5%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="#" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%2269b10396b28b3e31f5b7d7a7%22%7D%5D" target="" data-cta-copy="Claude now creates interactive charts, diagrams and visualizations" data-wf-native-id-path="8dae13c3-f4de-fbf4-c16a-42833b2e96f5_instance-0:0254e612-9509-0757-3332-f6be61ca688a_instance-0" data-wf-ao-click-engagement-tracking="true">Claude now creates interactive charts, diagrams and visualizations</a></p><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%220ae4cb74-2bf9-3661-7b2e-256f997eb798%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="https://claude.com/blog/claude-builds-visuals" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%2269b10396b28b3e31f5b7d7a7%22%7D%5D" target="" data-cta-copy="Claude now creates interactive charts, diagrams and visualizations" data-wf-native-id-path="0ae4cb74-2bf9-3661-7b2e-256f997eb798_instance-0:0254e612-9509-0757-3332-f6be61ca688a_instance-0" data-wf-ao-click-engagement-tracking="true">Claude now creates interactive charts, diagrams and visualizations</a></p></div><div role="listitem" class="blog_cms_item w-dyn-item card_blog_wrap"><div class="card_blog_visual_wrap card_blog_visual card_blog_hero"><img src="https://cdn.prod.website-files.com/68a44d4040f98a4adf2207b6/6903d229a7aa26ac1b6e96c2_a62b6eb169818f14c35b7a192af269e283f8fa93-1000x1000.svg" alt="" class="card_blog_illo" /></div><div class="card_blog_content"><div class="u-height-full"><p>Feb 17, 2026</p><h3 class="card_blog_title u-text-style-h6">Increase web search accuracy and efficiency with dynamic filtering</h3></div><div class="w-dyn-list w-dyn-items u-foreground-tertiary w-dyn-item card-main_tag-wrap"><p>Product announcements</p></div></div><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%228dae13c3-f4de-fbf4-c16a-42833b2e96f5%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="#" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%226990cd61e7fe68129c6b823e%22%7D%5D" target="" data-cta-copy="Increase web search accuracy and efficiency with dynamic filtering" data-wf-native-id-path="8dae13c3-f4de-fbf4-c16a-42833b2e96f5_instance-1:0254e612-9509-0757-3332-f6be61ca688a_instance-1" data-wf-ao-click-engagement-tracking="true">Increase web search accuracy and efficiency with dynamic filtering</a></p><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%220ae4cb74-2bf9-3661-7b2e-256f997eb798%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="https://claude.com/blog/improved-web-search-with-dynamic-filtering" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%226990cd61e7fe68129c6b823e%22%7D%5D" target="" data-cta-copy="Increase web search accuracy and efficiency with dynamic filtering" data-wf-native-id-path="0ae4cb74-2bf9-3661-7b2e-256f997eb798_instance-1:0254e612-9509-0757-3332-f6be61ca688a_instance-1" data-wf-ao-click-engagement-tracking="true">Increase web search accuracy and efficiency with dynamic filtering</a></p></div><div role="listitem" class="blog_cms_item w-dyn-item card_blog_wrap"><div class="card_blog_visual_wrap card_blog_visual card_blog_hero"><img src="https://cdn.prod.website-files.com/68a44d4040f98a4adf2207b6/6903d2287f90c57df4c9dd97_c1ef4c0b6882dfe985555b52999d370ea88a3c50-1000x1000.svg" alt="" class="card_blog_illo" /></div><div class="card_blog_content"><div class="u-height-full"><p>Mar 3, 2026</p><h3 class="card_blog_title u-text-style-h6">Improving skill-creator: Test, measure, and refine Agent Skills</h3></div><div class="w-dyn-list w-dyn-items u-foreground-tertiary w-dyn-item card-main_tag-wrap"><p>Claude Code</p></div></div><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%228dae13c3-f4de-fbf4-c16a-42833b2e96f5%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="#" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%2269a22e281ad8be9ef6a87b6e%22%7D%5D" target="" data-cta-copy="Improving skill-creator: Test, measure, and refine Agent Skills" data-wf-native-id-path="8dae13c3-f4de-fbf4-c16a-42833b2e96f5_instance-2:0254e612-9509-0757-3332-f6be61ca688a_instance-2" data-wf-ao-click-engagement-tracking="true">Improving skill-creator: Test, measure, and refine Agent Skills</a></p><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%220ae4cb74-2bf9-3661-7b2e-256f997eb798%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%2269a22e281ad8be9ef6a87b6e%22%7D%5D" target="" data-cta-copy="Improving skill-creator: Test, measure, and refine Agent Skills" data-wf-native-id-path="0ae4cb74-2bf9-3661-7b2e-256f997eb798_instance-2:0254e612-9509-0757-3332-f6be61ca688a_instance-2" data-wf-ao-click-engagement-tracking="true">Improving skill-creator: Test, measure, and refine Agent Skills</a></p></div><div role="listitem" class="blog_cms_item w-dyn-item card_blog_wrap"><div class="card_blog_visual_wrap card_blog_visual card_blog_hero"><img src="https://cdn.prod.website-files.com/68a44d4040f98a4adf2207b6/6903d22a8c18ce1b5adef7e9_6b1470e7fa2fb7280502291f204b88c412690076-1000x1000.svg" alt="" class="card_blog_illo" /></div><div class="card_blog_content"><div class="u-height-full"><p>Jan 26, 2026</p><h3 class="card_blog_title u-text-style-h6">Your favorite work tools are now interactive connectors inside Claude</h3></div><div class="w-dyn-list w-dyn-items u-foreground-tertiary w-dyn-item card-main_tag-wrap"><p>Product announcements</p></div></div><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%228dae13c3-f4de-fbf4-c16a-42833b2e96f5%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="#" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%22697342423c55c10b60af2801%22%7D%5D" target="" data-cta-copy="Your favorite work tools are now interactive connectors inside Claude" data-wf-native-id-path="8dae13c3-f4de-fbf4-c16a-42833b2e96f5_instance-3:0254e612-9509-0757-3332-f6be61ca688a_instance-3" data-wf-ao-click-engagement-tracking="true">Your favorite work tools are now interactive connectors inside Claude</a></p><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%220ae4cb74-2bf9-3661-7b2e-256f997eb798%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Related articles" data-wf-event-ids="" href="https://claude.com/blog/interactive-tools-in-claude" data-cta="Blog page" data-wf-cms-context="%5B%7B%22collectionId%22%3A%2268de89a1fbe1f683b08de151%22%2C%22itemId%22%3A%22697342423c55c10b60af2801%22%7D%5D" target="" data-cta-copy="Your favorite work tools are now interactive connectors inside Claude" data-wf-native-id-path="0ae4cb74-2bf9-3661-7b2e-256f997eb798_instance-3:0254e612-9509-0757-3332-f6be61ca688a_instance-3" data-wf-ao-click-engagement-tracking="true">Your favorite work tools are now interactive connectors inside Claude</a></p></div></div></div></section><section data-wf--section--theme="dark-3" class="u-section w-variant-1bfc31ae-0c03-d46c-ae82-d5b08aa25ed3" id=""><div class="section_contain u-container u-margin-trim u-threshold-medium"><div data-wf--grid--column-count="12" class="u-display-contents c-grid w-variant-fd7db3dc-d58a-e1d7-ed64-9b8a1a6798b5 u-grid-above u-gap-row-4"><div data-wf--content-wrapper--alignment="inherit" class="u-display-contents u-content-wrapper u-margin-trim u-align-self-center u-column-5 u-width-full"><p></p><h2>Transform how your organization operates with Claude</h2><div data-wf--button-wrapper--mobile-styling="full-width-mobile" class="u-display-contents u-button-group w-variant-92fe68b6-7437-d0c6-3fc0-cc8114f8d03d"><div data-wf--button-main--style="primary" class="button_main_wrap"><p>See pricing</p><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%2266f74833-d8fd-b1f3-8ebc-b729cc29bb73%22%2C%22instanceId%22%3A%22c52d6931-a739-e78a-51fc-51efe1f0f24a%22%7D%2C%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%225452a68c-3977-d772-6b86-a81d519c54c1%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Start building section" data-wf-event-ids="157059830" href="https://claude.com/pricing#api" data-cta="API page" target="" data-cta-copy="See pricing" data-wf-native-id-path="c52d6931-a739-e78a-51fc-51efe1f0f24a:5452a68c-3977-d772-6b86-a81d519c54c1:0254e612-9509-0757-3332-f6be61ca688a" data-wf-ao-click-engagement-tracking="true">See pricing</a></p></div><div data-wf--button-main--style="secondary" class="button_main_wrap w-variant-5df310d1-d3c2-0e0b-6186-54a1fb3311b6"><p>Contact sales</p><p><a class="clickable_link w-inline-block" data-wf-component-context="%5B%7B%22componentId%22%3A%2266f74833-d8fd-b1f3-8ebc-b729cc29bb73%22%2C%22instanceId%22%3A%22c52d6931-a739-e78a-51fc-51efe1f0f24c%22%7D%2C%7B%22componentId%22%3A%220254e612-9509-0757-3332-f6be61ca6889%22%2C%22instanceId%22%3A%225452a68c-3977-d772-6b86-a81d519c54c1%22%7D%5D" data-wf-element-id="0254e612-9509-0757-3332-f6be61ca688a" data-cta-position="Start building section" data-wf-event-ids="157059830" href="https://claude.com/contact-sales" data-cta="API page" target="" data-cta-copy="Contact sales" data-wf-native-id-path="c52d6931-a739-e78a-51fc-51efe1f0f24c:5452a68c-3977-d772-6b86-a81d519c54c1:0254e612-9509-0757-3332-f6be61ca688a" data-wf-ao-click-engagement-tracking="true">Contact sales</a></p></div></div></div><div class="u-display-contents u-column-7 u-flex-vertical-nowrap card_slot_wrap u-gap-row-1-5 u-max-width-50ch u-theme-dark-2 u-align-self-end u-max-width-unset-below u-display-contents u-display-contents u-content-wrapper u-margin-trim u-align-self-center u-width-full u-flex-vertical-nowrap u-align-items-start u-gap-row-1-5"><div data-wf--typography-paragraph--font-style="body-2" class="c-paragraph w-variant-61d538b2-709c-eb7a-4258-8c0890dc07fc u-text-wrap-pretty w-richtext u-mb-text u-rich-text"><p>Product updates, how-tos, community spotlights, and more. Delivered monthly to your inbox.</p></div><div class="form_newsletter_wrap w-form"><p>Thank you! You’re subscribed.</p><p>Sorry, there was a problem with your submission, please try again later.</p></div></div></div></div></section></main><div class="u-display-none"><p>Claude Code</p><p>Coding</p></div>]]></description>
      <link>https://claude.com/blog/code-review</link>
      <guid>https://claude.com/blog/code-review</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[superpowers]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">Superpowers</h1><a id="user-content-superpowers" class="anchor" aria-label="Permalink: Superpowers" href="#superpowers"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Superpowers is a complete software development workflow for your coding agents, built on top of a set of composable "skills" and some initial instructions that make sure your agent uses them.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">How it works</h2><a id="user-content-how-it-works" class="anchor" aria-label="Permalink: How it works" href="#how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">It starts from the moment you fire up your coding agent. As soon as it sees that you're building something, it <em>doesn't</em> just jump into trying to write code. Instead, it steps back and asks you what you're really trying to do.</p>
<p dir="auto">Once it's teased a spec out of the conversation, it shows it to you in chunks short enough to actually read and digest.</p>
<p dir="auto">After you've signed off on the design, your agent puts together an implementation plan that's clear enough for an enthusiastic junior engineer with poor taste, no judgement, no project context, and an aversion to testing to follow. It emphasizes true red/green TDD, YAGNI (You Aren't Gonna Need It), and DRY.</p>
<p dir="auto">Next up, once you say "go", it launches a <em>subagent-driven-development</em> process, having agents work through each engineering task, inspecting and reviewing their work, and continuing forward. It's not uncommon for Claude to be able to work autonomously for a couple hours at a time without deviating from the plan you put together.</p>
<p dir="auto">There's a bunch more to it, but that's the core of the system. And because the skills trigger automatically, you don't need to do anything special. Your coding agent just has Superpowers.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Sponsorship</h2><a id="user-content-sponsorship" class="anchor" aria-label="Permalink: Sponsorship" href="#sponsorship"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If Superpowers has helped you do stuff that makes money and you are so inclined, I'd greatly appreciate it if you'd consider <a href="https://github.com/sponsors/obra">sponsoring my opensource work</a>.</p>
<p dir="auto">Thanks!</p>
<ul dir="auto">
<li>Jesse</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Installation</h2><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Note:</strong> Installation differs by platform. Claude Code or Cursor have built-in plugin marketplaces. Codex and OpenCode require manual setup.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Claude Code Official Marketplace</h3><a id="user-content-claude-code-official-marketplace" class="anchor" aria-label="Permalink: Claude Code Official Marketplace" href="#claude-code-official-marketplace"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Superpowers is available via the <a href="https://claude.com/plugins/superpowers" rel="nofollow">official Claude plugin marketplace</a></p>
<p dir="auto">Install the plugin from Claude marketplace:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/plugin install superpowers@claude-plugins-official"><pre>/plugin install superpowers@claude-plugins-official</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Claude Code (via Plugin Marketplace)</h3><a id="user-content-claude-code-via-plugin-marketplace" class="anchor" aria-label="Permalink: Claude Code (via Plugin Marketplace)" href="#claude-code-via-plugin-marketplace"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">In Claude Code, register the marketplace first:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/plugin marketplace add obra/superpowers-marketplace"><pre>/plugin marketplace add obra/superpowers-marketplace</pre></div>
<p dir="auto">Then install the plugin from this marketplace:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/plugin install superpowers@superpowers-marketplace"><pre>/plugin install superpowers@superpowers-marketplace</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Cursor (via Plugin Marketplace)</h3><a id="user-content-cursor-via-plugin-marketplace" class="anchor" aria-label="Permalink: Cursor (via Plugin Marketplace)" href="#cursor-via-plugin-marketplace"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">In Cursor Agent chat, install from marketplace:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/add-plugin superpowers"><pre lang="text" class="notranslate"><code>/add-plugin superpowers
</code></pre></div>
<p dir="auto">or search for "superpowers" in the plugin marketplace.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Codex</h3><a id="user-content-codex" class="anchor" aria-label="Permalink: Codex" href="#codex"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Tell Codex:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md"><pre class="notranslate"><code>Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md
</code></pre></div>
<p dir="auto"><strong>Detailed docs:</strong> <a href="docs/README.codex.md">docs/README.codex.md</a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">OpenCode</h3><a id="user-content-opencode" class="anchor" aria-label="Permalink: OpenCode" href="#opencode"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Tell OpenCode:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.opencode/INSTALL.md"><pre class="notranslate"><code>Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.opencode/INSTALL.md
</code></pre></div>
<p dir="auto"><strong>Detailed docs:</strong> <a href="docs/README.opencode.md">docs/README.opencode.md</a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Gemini CLI</h3><a id="user-content-gemini-cli" class="anchor" aria-label="Permalink: Gemini CLI" href="#gemini-cli"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gemini extensions install https://github.com/obra/superpowers"><pre>gemini extensions install https://github.com/obra/superpowers</pre></div>
<p dir="auto">To update:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gemini extensions update superpowers"><pre>gemini extensions update superpowers</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Verify Installation</h3><a id="user-content-verify-installation" class="anchor" aria-label="Permalink: Verify Installation" href="#verify-installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Start a new session in your chosen platform and ask for something that should trigger a skill (for example, "help me plan this feature" or "let's debug this issue"). The agent should automatically invoke the relevant superpowers skill.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">The Basic Workflow</h2><a id="user-content-the-basic-workflow" class="anchor" aria-label="Permalink: The Basic Workflow" href="#the-basic-workflow"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>
<p dir="auto"><strong>brainstorming</strong> - Activates before writing code. Refines rough ideas through questions, explores alternatives, presents design in sections for validation. Saves design document.</p>
</li>
<li>
<p dir="auto"><strong>using-git-worktrees</strong> - Activates after design approval. Creates isolated workspace on new branch, runs project setup, verifies clean test baseline.</p>
</li>
<li>
<p dir="auto"><strong>writing-plans</strong> - Activates with approved design. Breaks work into bite-sized tasks (2-5 minutes each). Every task has exact file paths, complete code, verification steps.</p>
</li>
<li>
<p dir="auto"><strong>subagent-driven-development</strong> or <strong>executing-plans</strong> - Activates with plan. Dispatches fresh subagent per task with two-stage review (spec compliance, then code quality), or executes in batches with human checkpoints.</p>
</li>
<li>
<p dir="auto"><strong>test-driven-development</strong> - Activates during implementation. Enforces RED-GREEN-REFACTOR: write failing test, watch it fail, write minimal code, watch it pass, commit. Deletes code written before tests.</p>
</li>
<li>
<p dir="auto"><strong>requesting-code-review</strong> - Activates between tasks. Reviews against plan, reports issues by severity. Critical issues block progress.</p>
</li>
<li>
<p dir="auto"><strong>finishing-a-development-branch</strong> - Activates when tasks complete. Verifies tests, presents options (merge/PR/keep/discard), cleans up worktree.</p>
</li>
</ol>
<p dir="auto"><strong>The agent checks for relevant skills before any task.</strong> Mandatory workflows, not suggestions.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">What's Inside</h2><a id="user-content-whats-inside" class="anchor" aria-label="Permalink: What's Inside" href="#whats-inside"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Skills Library</h3><a id="user-content-skills-library" class="anchor" aria-label="Permalink: Skills Library" href="#skills-library"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Testing</strong></p>
<ul dir="auto">
<li><strong>test-driven-development</strong> - RED-GREEN-REFACTOR cycle (includes testing anti-patterns reference)</li>
</ul>
<p dir="auto"><strong>Debugging</strong></p>
<ul dir="auto">
<li><strong>systematic-debugging</strong> - 4-phase root cause process (includes root-cause-tracing, defense-in-depth, condition-based-waiting techniques)</li>
<li><strong>verification-before-completion</strong> - Ensure it's actually fixed</li>
</ul>
<p dir="auto"><strong>Collaboration</strong></p>
<ul dir="auto">
<li><strong>brainstorming</strong> - Socratic design refinement</li>
<li><strong>writing-plans</strong> - Detailed implementation plans</li>
<li><strong>executing-plans</strong> - Batch execution with checkpoints</li>
<li><strong>dispatching-parallel-agents</strong> - Concurrent subagent workflows</li>
<li><strong>requesting-code-review</strong> - Pre-review checklist</li>
<li><strong>receiving-code-review</strong> - Responding to feedback</li>
<li><strong>using-git-worktrees</strong> - Parallel development branches</li>
<li><strong>finishing-a-development-branch</strong> - Merge/PR decision workflow</li>
<li><strong>subagent-driven-development</strong> - Fast iteration with two-stage review (spec compliance, then code quality)</li>
</ul>
<p dir="auto"><strong>Meta</strong></p>
<ul dir="auto">
<li><strong>writing-skills</strong> - Create new skills following best practices (includes testing methodology)</li>
<li><strong>using-superpowers</strong> - Introduction to the skills system</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Philosophy</h2><a id="user-content-philosophy" class="anchor" aria-label="Permalink: Philosophy" href="#philosophy"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Test-Driven Development</strong> - Write tests first, always</li>
<li><strong>Systematic over ad-hoc</strong> - Process over guessing</li>
<li><strong>Complexity reduction</strong> - Simplicity as primary goal</li>
<li><strong>Evidence over claims</strong> - Verify before declaring success</li>
</ul>
<p dir="auto">Read more: <a href="https://blog.fsck.com/2025/10/09/superpowers/" rel="nofollow">Superpowers for Claude Code</a></p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Skills live directly in this repository. To contribute:</p>
<ol dir="auto">
<li>Fork the repository</li>
<li>Create a branch for your skill</li>
<li>Follow the <code>writing-skills</code> skill for creating and testing new skills</li>
<li>Submit a PR</li>
</ol>
<p dir="auto">See <code>skills/writing-skills/SKILL.md</code> for the complete guide.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Updating</h2><a id="user-content-updating" class="anchor" aria-label="Permalink: Updating" href="#updating"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Skills update automatically when you update the plugin:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/plugin update superpowers"><pre>/plugin update superpowers</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT License - see LICENSE file for details</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Support</h2><a id="user-content-support" class="anchor" aria-label="Permalink: Support" href="#support"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Issues</strong>: <a href="https://github.com/obra/superpowers/issues">https://github.com/obra/superpowers/issues</a></li>
<li><strong>Marketplace</strong>: <a href="https://github.com/obra/superpowers-marketplace">https://github.com/obra/superpowers-marketplace</a></li>
</ul>
</article></div>]]></description>
      <link>https://github.com/obra/superpowers</link>
      <guid>https://github.com/obra/superpowers</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How to Talk to Someone Experiencing 'AI Psychosis': Mental health experts say identifying when someone is in need of help is the first step — and approaching them with careful compassion is the hardest, most essential part that follows | 404 Media]]></title>
      <description><![CDATA[<div class="post-sneak-peek fading">
<p>When David saw his friend Michael’s social media post asking for a second opinion on a programming project, he offered to take a look.</p>
<p>“He sent me some of the code, and none of it made sense, none of it ran correctly. Or if it did run, it didn't do anything,” David told me. David and his friend’s names have been changed in this story to protect their privacy. “So I'm like, ‘What is this? Can you give me more context about this?’ And Michael’s like, ‘Oh, yeah, I've been messing around with ChatGPT a lot.’” </p>
<p>Michael then sent David thousands of pages of ChatGPT conversations, much of it lines of code that didn’t work. Interspersed in the ChatGPT code were musings about spirituality and quantum physics, tetrahedral structures, base particles, and multi-dimensional interactions. “It's very like, woo woo,” David told me. “And we ended up having this interesting conversation about, how do you know that ChatGPT isn't lying?” </p>
<p>As their conversation turned from broken code to physics concepts and quantum entanglement, David realized something was very wrong. Talking to his friend — whom he’d shared many deep conversations with over the years, unpacking matters of religion and theories about the world and how people perceive it — suddenly felt like talking to a cultist. Michael thought he, through ChatGPT, discovered a critical flaw in humanity’s understanding of physics.</p>
<p>“ChatGPT had convinced him that all of this was so obviously true,” David said. “The way he spoke about it was as if it were obvious. Genuinely, I felt like I was talking to a cult member.” </p>
<div class="kg-card kg-callout-card kg-callout-card-grey">

<div class="kg-callout-text"><strong><strong class="c1">Do you have experience with AI psychosis? I would love to hear from you. Using a non-work device, you can message me securely on Signal at sam.404. Otherwise, send me an email at sam@404media.co.</strong></strong></div>
</div>
<p>But at the time, David didn’t have a way to name, or even describe, what his friend was experiencing. Once he started hearing the phrase “AI psychosis” to describe other peoples’ problematic relationships with chatbots, he wondered if that’s what was happening to Michael. His friend was clearly grappling with some kind of delusion related to what the chatbot was telling him. But there’s no handbook or program for how to talk to a friend or family member in that situation. Having encountered these kinds of conversations myself and feeling similarly uncertain, I talked to mental health experts about how to talk to someone who appears to be embracing delusional ideas after spending too much time with a chatbot. </p>
</div>
<div class="post-access-cta p-lg text-center paid">
<div class="paid">
<h2>This post is for paid members only</h2>
<div class="description">Become a paid member for unlimited ad-free access to articles, bonus podcast content, and more.</div>
<a class="btn btn--brand m-b-lg" href="https://www.404media.co/membership/">Subscribe</a></div>
<div class="members">
<h2>Sign up for free access to this post</h2>
<div class="description">Free members get access to posts like this one along with an email round-up of our week's stories.</div>
<a class="btn btn--brand m-b-lg" href="https://www.404media.co/signup/">Subscribe</a></div>
<div class="sign-in">Already have an account? <a class="post-access-alt" href="https://www.404media.co/signin/" data-portal="signin">Sign in</a></div>
</div>]]></description>
      <link>https://www.404media.co/ai-psychosis-help-gemini-chatgpt-claude-chatbot-delusions/</link>
      <guid>https://www.404media.co/ai-psychosis-help-gemini-chatgpt-claude-chatbot-delusions/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[GitHub - kantord/blogtato: A CLI RSS/Atom feed reader inspired by Taskwarrior · GitHub]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">blogtato</h1><a id="user-content-blogtato" class="anchor" aria-label="Permalink: blogtato" href="#blogtato"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A CLI RSS/Atom feed reader inspired by Taskwarrior.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="demo/demo.gif"><img src="demo/demo.gif" alt="demo" data-animated-image="" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Features</h2><a id="user-content-features" class="anchor" aria-label="Permalink: Features" href="#features"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>Subscribe to RSS and Atom feeds</li>
<li>Simple query language for filtering by feed, read status, and date, with
grouping and export</li>
<li>Git-based sync across machines with conflict-free merge
(<a href="#design-philosophy">why git?</a>)</li>
<li>No accounts, no servers, no continuous network dependency</li>
<li>Mark content as read</li>
<li>Designed to be distraction free, minimalistic and work out of the box</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Install</h2><a id="user-content-install" class="anchor" aria-label="Permalink: Install" href="#install"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cargo install blogtato"><pre>cargo install blogtato</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Git sync</h3><a id="user-content-git-sync" class="anchor" aria-label="Permalink: Git sync" href="#git-sync"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>git</code> based synchronization is entire optional. <code>blogtato</code> can work entirely
offline on a single device.</p>
<p dir="auto">To set up git synchronization, create a private repo on your git host, then:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# On your first machine
blog clone user/repo

# From now on, sync fetches feeds and pushes/pulls from the remote
# with no remote repository, `blog sync` just pulls the latest posts from
# all feeds
blog sync"><pre><span class="pl-c"><span class="pl-c">#</span> On your first machine</span>
blog clone user/repo

<span class="pl-c"><span class="pl-c">#</span> From now on, sync fetches feeds and pushes/pulls from the remote</span>
<span class="pl-c"><span class="pl-c">#</span> with no remote repository, `blog sync` just pulls the latest posts from</span>
<span class="pl-c"><span class="pl-c">#</span> all feeds</span>
blog sync</pre></div>
<p dir="auto">On your device(s), run the same <code>blog clone</code> to pull down your feeds and posts.</p>
<p dir="auto">Don't worry about setting git sync up if you are just trying <code>blogtato</code> out:
you can run <code>blog clone user/repo</code> later and your existing feeds will be merged
with the remote automatically.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Quick start</h3><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Once you set up your <code>git</code>-based sync, or if you decided to skip it, subscribe
to your favorite feeds using <code>blog feed add</code>:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="blog feed add https://michael.stapelberg.ch
blog feed add https://www.justinmklam.com"><pre>blog feed add https://michael.stapelberg.ch
blog feed add https://www.justinmklam.com</pre></div>
<p dir="auto">You can import your subscriptions from other RSS readers
(<a href="https://docs.feedly.com/article/52-how-can-i-export-my-sources-and-feeds-through-opml" rel="nofollow">Feedly</a>,
<a href="https://www.inoreader.com/blog/2014/05/opml-subscriptions.html" rel="nofollow">Inoreader</a>,
<a href="https://netnewswire.com/help/mac/5.0/en/export-opml.html" rel="nofollow">NetNewsWire</a>,
<a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" rel="nofollow">FreshRSS</a>,
<a href="https://news.nononsenseapps.com/posts/2.5.0_opml/" rel="nofollow">Feeder</a>,
<a href="https://tt-rss.org/docs/Installation-Guide.html#opml" rel="nofollow">Tiny Tiny RSS</a>,
<a href="https://support.microsoft.com/en-us/office/share-or-export-rss-feeds-5b514f38-8671-447c-8c25-7f02cc0833e0" rel="nofollow">Outlook</a>,
and others) using an OPML file:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="blog feed import feeds.opml"><pre>blog feed import feeds.opml</pre></div>
<p dir="auto">Fetch and list latest posts:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="blog sync
blog"><pre>blog sync
blog</pre></div>
<p dir="auto">Read whatever you found interesting by referring to its shorthand</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="blog df read"><pre>blog df <span class="pl-c1">read</span></pre></div>
<p dir="auto">You can subscribe to <code>blogtato</code> releases to know when new features or fixes are
available:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="blog feed add https://github.com/kantord/blogtato/releases.atom"><pre>blog feed add https://github.com/kantord/blogtato/releases.atom</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Usage examples</h2><a id="user-content-usage-examples" class="anchor" aria-label="Permalink: Usage examples" href="#usage-examples"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Subscribe to a feed
blog feed add https://news.ycombinator.com/rss

# Fetch new posts and sync with git remote
blog sync

# Show posts (defaults to unread posts from the last 3 months, grouped by week)
blog

# Group by date, week, or feed
blog /d
blog /w
blog /f

# Combine groupings
blog /d /f

# Filter by feed shorthand
blog @hn

# Filter by read status
blog .unread
blog .read
blog .all

# Filter by date
blog 1w..
blog 3m..1m
blog /d 2w..1w

# Combine filters - list unread posts form HackerNews grouped by date
blog @hn .unread /d

# Open a post in the default browser
blog abc open

# Print a post URL (useful with CLI browsers)
blog abc read
w3m $(blog abc read)

# Mark a post as unread
blog abc unread

# Export matching posts as JSONL
blog .all export
blog @myblog export
blog 1w.. export

# List subscriptions
blog feed ls

# Remove a feed
blog feed rm https://news.ycombinator.com/rss
blog feed rm @hn"><pre><span class="pl-c"><span class="pl-c">#</span> Subscribe to a feed</span>
blog feed add https://news.ycombinator.com/rss

<span class="pl-c"><span class="pl-c">#</span> Fetch new posts and sync with git remote</span>
blog sync

<span class="pl-c"><span class="pl-c">#</span> Show posts (defaults to unread posts from the last 3 months, grouped by week)</span>
blog

<span class="pl-c"><span class="pl-c">#</span> Group by date, week, or feed</span>
blog /d
blog /w
blog /f

<span class="pl-c"><span class="pl-c">#</span> Combine groupings</span>
blog /d /f

<span class="pl-c"><span class="pl-c">#</span> Filter by feed shorthand</span>
blog @hn

<span class="pl-c"><span class="pl-c">#</span> Filter by read status</span>
blog .unread
blog .read
blog .all

<span class="pl-c"><span class="pl-c">#</span> Filter by date</span>
blog 1w..
blog 3m..1m
blog /d 2w..1w

<span class="pl-c"><span class="pl-c">#</span> Combine filters - list unread posts form HackerNews grouped by date</span>
blog @hn .unread /d

<span class="pl-c"><span class="pl-c">#</span> Open a post in the default browser</span>
blog abc open

<span class="pl-c"><span class="pl-c">#</span> Print a post URL (useful with CLI browsers)</span>
blog abc <span class="pl-c1">read</span>
w3m <span class="pl-s"><span class="pl-pds">$(</span>blog abc read<span class="pl-pds">)</span></span>

<span class="pl-c"><span class="pl-c">#</span> Mark a post as unread</span>
blog abc unread

<span class="pl-c"><span class="pl-c">#</span> Export matching posts as JSONL</span>
blog .all <span class="pl-k">export</span>
blog @myblog <span class="pl-k">export</span>
blog 1w.. <span class="pl-k">export</span>

<span class="pl-c"><span class="pl-c">#</span> List subscriptions</span>
blog feed ls

<span class="pl-c"><span class="pl-c">#</span> Remove a feed</span>
blog feed rm https://news.ycombinator.com/rss
blog feed rm @hn</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Design philosophy</h2><a id="user-content-design-philosophy" class="anchor" aria-label="Permalink: Design philosophy" href="#design-philosophy"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">I built <code>blogtato</code> around the idea of subscription detox and simplicity. I just
wanted to use a simple and RSS reader that is not distracting, but can be
synced between different devices seamlessly without having to set up another
user account and paying another monthly subscription fee.</p>
<p dir="auto"><code>blogtato</code> uses a simple database that stores data in JSONL files and syncs
them using <code>git</code>. From a performance standpoint, this is admittedly
sub-optimal, and an quite esoteric design. At the same time, if you are
comfortable with CLI tools you likely have access to a remote <code>git</code> host such
as GitHub, GitLab or a Forgejo instance: and that's all <code>blogtato</code> needs to be
able to keep data up to date on all of your devices. From a user perspective,
this just works with effectively zero configuration.</p>
<p dir="auto"><code>blogtato</code>'s database uses a conflict-free design: even if you have diverging
changes between different devices, you will never have to manually resolve
conflicts. You can forget about <code>git</code> being there.</p>
<p dir="auto">Network operations are always initiated by the user. There is no need for a
continuously running server. And all operations that don't strictly need
network access work offline.</p>
<p dir="auto">It is my goal to keep the feature-set and the complexity of this project down,
so that it can be maintained with minimal effort and can be considered to be
"done".</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Naming</h2><a id="user-content-naming" class="anchor" aria-label="Permalink: Naming" href="#naming"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The naming is meant to symbolize simplicity and pragmatic silliness: I just
mashed the word "blog" together with the first word I could think of: potato.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Comparison with alternatives</h2><a id="user-content-comparison-with-alternatives" class="anchor" aria-label="Permalink: Comparison with alternatives" href="#comparison-with-alternatives"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>blogtato</code> is relatively new and there are several good, and more mature
alternatives. This section attempts to summarize how they differ from
<code>blogtato</code> and why some users might still prefer to use <code>blogtato</code> instead.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto"><a href="https://newsboat.org/" rel="nofollow">Newsboat</a></h3><a id="user-content-newsboat" class="anchor" aria-label="Permalink: Newsboat" href="#newsboat"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Newsboat is a very mature TUI RSS client with a wide range of features that
<code>blogtato</code> does <em>not</em> have. Just like <code>blogtato</code>, it supports local-only
workflows.</p>
<p dir="auto">It can also act as a client to remote servers, so if you are ok with having to
self-host a server or signing up to a hosted server, then <code>blogtato</code>'s <code>git</code>
sync feature is not a relevant differentiator for you.</p>
<p dir="auto">Another reason why <code>blogtato</code> might be relevant to you is that it has a
Taskwarrior-like interface that is even more minimalistic than Newsboat.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto"><a href="https://codeberg.org/newsraft/newsraft" rel="nofollow">Newsraft</a></h3><a id="user-content-newsraft" class="anchor" aria-label="Permalink: Newsraft" href="#newsraft"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Newsraft is a more minimalistic alternative to Newsboat. The
<a href="#newsboat">Newsboat</a> breakdown mostly applies.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto"><a href="https://freshrss.org/" rel="nofollow">FreshRSS</a>, <a href="https://miniflux.app/" rel="nofollow">Miniflux</a> &amp; <a href="https://tt-rss.org/" rel="nofollow">Tiny Tiny RSS</a></h3><a id="user-content-freshrss-miniflux--tiny-tiny-rss" class="anchor" aria-label="Permalink: FreshRSS, Miniflux &amp; Tiny Tiny RSS" href="#freshrss-miniflux--tiny-tiny-rss"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">These are mature, self-hostable web-based RSS readers/aggregators. What
<code>blogtato</code> offers in comparison is a minimalistic CLI interface and effectively
zero-setup sync between different machines using <code>git</code>, without the need for an
additional, continuously running server.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto"><a href="https://feedly.com/" rel="nofollow">Feedly</a>, <a href="https://www.inoreader.com/" rel="nofollow">Inoreader</a></h3><a id="user-content-feedly-inoreader" class="anchor" aria-label="Permalink: Feedly, Inoreader" href="#feedly-inoreader"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">These are full-featured web-based services. If you are a heavy RSS-user and
like the user interfaces and features they offer (such as GUI apps for iOS and
Android, content recommendations) you will likely prefer one of these options.</p>
<p dir="auto">You could find <code>blogtato</code> interesting if you'd prefer a more minimalistic,
distraction-free CLI interface and do not need their advanced features.</p>
</article></div>]]></description>
      <link>https://github.com/kantord/blogtato</link>
      <guid>https://github.com/kantord/blogtato</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Why can’t you tune your guitar? | The Ethan Hein Blog]]></title>
      <description><![CDATA[I continue to refine and tighten up my explanation of tuning and temperament systems, one of the least understood music theory concepts out there. Hope this is useful to you. Comments and corrections welcome.]]></description>
      <link>https://www.ethanhein.com/wp/2019/why-cant-you-tune-your-guitar/</link>
      <guid>https://www.ethanhein.com/wp/2019/why-cant-you-tune-your-guitar/</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[FontCrafter: Create Your Handwriting Font for Free]]></title>
      <description><![CDATA[<div class="modal-overlay modal" id="helpModal"><h2>About FontCrafter</h2><p class="c2">FontCrafter turns your handwriting into a real, installable font — entirely in your browser. No accounts, no uploads to servers, no cost.</p><p class="c2">Still have questions? <a href="#" class="c3">Here's our FAQ.</a></p><div class="modal-section"><h4>How does it work?</h4><p>Drop in a scan of your handwriting. The app detects each character, traces vector outlines, and builds a working OpenType font file you can install anywhere. Everything runs locally — your handwriting never leaves your device.</p></div><div class="modal-section"><h4>Who is it for?</h4><p>Anyone who wants a personal handwriting font — designers, teachers, content creators, or anyone who thinks their handwriting deserves to be a typeface.</p></div><p><a href="https://arcade.pirillo.com/" target="_blank">More of My Apps</a> <a href="https://chris.pirillo.com/" target="_blank">Follow Chris Pirillo</a> <a href="https://ctrlaltcreate.live/" target="_blank">Learn How to Make Apps</a> <a href="https://www.paypal.com/donate/?hosted_button_id=UMWCDWGVXVHZU" target="_blank">Donate to Me Here</a> <a href="https://patreon.com/ChrisPirillo" target="_blank">Support My Patreon</a></p></div><div class="modal-overlay modal c4" id="faqModal"><h2>Frequently Asked Questions</h2><div class="faq-item"><h4>Is FontCrafter really free?</h4><p>Yes — completely free with no hidden limits. There's no account required, no watermarks, no feature gates, and no premium tier. You get full access to OTF, TTF, WOFF2, and Base64 exports, plus ligature generation. Your font files are yours to keep and use however you want.</p></div><div class="faq-item"><h4>Do I need to create an account?</h4><p>No. FontCrafter requires zero signup. Open the page, load your scan, build your font, download it. No email, no password, no account whatsoever.</p></div><div class="faq-item"><h4>Is my handwriting uploaded to a server?</h4><p>No. Everything runs locally in your browser using JavaScript. Your scan never leaves your device — no server processing, no cloud storage, no data collection. This is a fully client-side application.</p></div><div class="faq-item"><h4>What font formats can I export?</h4><p>FontCrafter exports four formats: <strong>OTF</strong> (OpenType, best for desktop apps like Word and Photoshop), <strong>TTF</strong> (TrueType, universal compatibility), <strong>WOFF2</strong> (compressed web font for websites), and <strong>Base64</strong> (for embedding directly in CSS). All formats are generated locally.</p></div><div class="faq-item"><h4>Does FontCrafter support ligatures?</h4><p>Yes. FontCrafter can auto-generate ligatures — connected letter pairs like "ff," "fi," "th," and "st" that make your font flow naturally. It also supports contextual alternates, cycling between your handwriting variants for a more organic feel. Many competing tools charge for ligature support.</p></div><div class="faq-item"><h4>How is this different from Calligraphr?</h4><p>Calligraphr requires an account and processes your handwriting on their servers. Ligatures and advanced features require a paid subscription ($8/month). FontCrafter is 100% free, requires no account, processes everything locally in your browser, and includes ligatures, contextual alternates, and color font effects (drop shadows and ink texture) at no cost. FontCrafter also exports WOFF2 and Base64 formats that Calligraphr doesn't offer.</p></div><div class="faq-item"><h4>What kind of pen should I use?</h4><p>A dark felt-tip pen (0.5mm or thicker) gives the best results. Ballpoints are often too faint, and thick markers can bleed. Keep your strokes inside the boxes with a little breathing room from the edges.</p></div><div class="faq-item"><h4>Can I use my font commercially?</h4><p>The font is generated from your own handwriting, so you own it. You can use it for personal projects, commercial work, branding, merchandise — anything. Just make sure the handwriting is yours or you have permission from the person whose handwriting was used.</p></div></div><div class="modal-overlay modal c7" id="nerdModal"><h2 class="c5">Under the Hood</h2><p class="c6">Everything below happens entirely in your browser. No server, no WebAssembly binary, no hidden dependencies — just JavaScript running on your device.</p><div class="modal-section"><h4>The Processing Pipeline</h4><p>When you drop in a scan, FontCrafter runs a multi-stage image processing pipeline: adaptive thresholding to isolate ink from paper, connected-component blob detection to find individual characters, Suzuki-Abe contour tracing to extract outlines, Ramer-Douglas-Peucker (RDP) simplification to reduce point count, Chaikin corner-cutting for smooth curves, and cubic Bézier fitting to produce clean vector paths. The entire pipeline is tuned for handwriting — pen pressure variation, stroke overlap, and ink bleed are all accounted for.</p></div><div class="modal-section"><h4>Font Architecture</h4><p>FontCrafter builds fully compliant OpenType fonts from scratch — not a template with swapped glyphs, but real font table construction. The standard font uses CFF (Compact Font Format) outlines with cubic Bézier curves at 1000 UPM (units per em). Metrics are calculated from your actual handwriting: ascender, descender, cap height, and x-height are derived from the scanned characters, not hard-coded values.</p></div><div class="modal-section"><h4>OpenType Features</h4><p>Your font includes a GSUB (Glyph Substitution) table with two key features. <strong>Contextual Alternates (calt):</strong> FontCrafter stores up to 3 handwriting variants per character and builds lookup rules that cycle between them as you type, so repeated letters never look identical — the same trick professional handwriting fonts use. <strong>Ligatures (liga):</strong> Common letter pairs like ff, fi, fl, th, and st are composited from your existing characters with overlap and kerning adjustments, then injected as ligature substitutions. Both features are baked into the font binary — they work in any app with OpenType support (Word, Pages, Photoshop, InDesign, Figma, CSS).</p></div><div class="modal-section"><h4>Kerning</h4><p>FontCrafter generates kern pairs using a class-based approach. Characters are grouped by shape (round letters like O, C, G share one class; diagonal letters like A, V, W share another), then pair-specific adjustments are applied so combinations like AV, To, and WA sit together naturally. You can choose tight, normal, or loose spacing — each adjusts the kern values proportionally.</p></div><div class="modal-section"><h4>Composite &amp; Extended Characters</h4><p>The standard font can exceed 500 glyphs, most generated automatically. Accented characters (à, ñ, ü, ø, and 100+ more) are built by compositing your base letters with programmatically positioned diacritical marks. Extended characters — smart quotes, fractions, currency symbols, circled letters, superscripts — are constructed by combining, scaling, flipping, and repositioning your existing strokes. Nothing is pulled from a system font or generic template.</p></div><div class="modal-section"><h4>Color Fonts (COLR/CPAL)</h4><p>The color font option builds a COLR (Color Outline) table with a CPAL (Color Palette) for multi-layer rendering. Drop shadows use a duplicate glyph layer offset and painted with the shadow color beneath the primary layer. Ink texture uses a noise-based edge erosion algorithm to create an organic, hand-inked look with two color layers. Duo-tone splits each glyph horizontally with a configurable split point. These are real COLRv0 fonts — they render natively in Chrome, Edge, Firefox, Safari, and any app that supports OpenType color fonts.</p></div><div class="modal-section"><h4>Output Formats</h4><p><strong>OTF (OpenType/CFF):</strong> Cubic Bézier outlines, best quality for desktop apps — Word, Photoshop, InDesign, Figma. <strong>TTF (TrueType):</strong> Quadratic Bézier outlines converted from CFF, maximum compatibility across platforms and older software. <strong>WOFF2:</strong> Brotli-compressed OTF wrapped in a web font container — typically 30-50% smaller than raw OTF, optimized for CSS @font-face. <strong>Base64:</strong> The full OTF binary encoded as a base64 data URI, ready to paste directly into a CSS @font-face rule — zero external file dependencies. All four formats are generated client-side using ArrayBuffer construction and binary table assembly.</p></div><div class="modal-section"><h4>What You Don't Get (Yet)</h4><p>FontCrafter doesn't currently support: variable fonts (OpenType fvar), hinting/instruction programs (TrueType bytecode), right-to-left scripts, CJK character sets, or multi-page template scanning. These may come in future updates.</p></div></div>]]></description>
      <link>https://arcade.pirillo.com/fontcrafter.html</link>
      <guid>https://arcade.pirillo.com/fontcrafter.html</guid>
      <pubDate>Thu, 12 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Building Typographic Scales in CSS with :heading(), sibling-index(), and pow()]]></title>
      <description><![CDATA[<p>In <a href="https://www.alwaystwisted.com/articles/styling-with-the-heading-pseudo-class">my previous article</a>, I introduced the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:heading"><code>:heading</code> pseudo-class</a> and showed how it can simplify styling all headings in groups, or all at once. Today, I want to take that much further and show how combining <code>:heading()</code> with two other CSS features—<code>sibling-index()</code> and <code>pow()</code> lets us build flexible, maintainable typographic scales with just a few lines of code.</p><div class="at-c-note"><p><strong>Important limitation:</strong> <code>sibling-index()</code> counts <em>siblings</em>, not heading levels. That means the scale only lines up if you have a clean, ordered run of <code>h1</code> → <code>h6</code>. If you repeat a heading level (for example: <code>h1</code>, <code>h2</code>, <code>h3</code>, <code>h3</code>), the second <code>h3</code> will be sized like <code>h4</code> because its sibling index is higher. Keep that in mind if you use this pattern in real layouts.</p></div><p>There’s still a lot to like here, but the ordering limitation matters in real content.</p><p>If you want the version that works regardless of heading order, skip to <a href="#what-works-in-real-layouts">What Works in Real Layouts</a>.</p><h2 id="the-problem-with-traditional-typographic-scales" tabindex="-1">The Problem with Traditional Typographic Scales</h2><p>When you implement a typographic scale in CSS today, you may end up with something like this.</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">h1 {
  font-size: 3.052rem;
}
h2 {
  font-size: 2.441rem;
}
h3 {
  font-size: 1.953rem;
}
h4 {
  font-size: 1.563rem;
}
h5 {
  font-size: 1.25rem;
}
h6 {
  font-size: 1rem;
}</pre></figure><p>This works, but it's repetitive.</p><p>Separate declarations for what's essentially a mathematical pattern. It may be inflexible too. Want to try a different ratio? You'll need to recalculate all the values manually, which could be error prone when dealing with exponential calculations. The relationship between values isn't expressed in the code itself, which could make it harder to understand and maintain.</p><p>What we really want is to define the pattern once and let CSS calculate the individual values for us.</p><h2 id="understanding-typographic-scales" tabindex="-1">Understanding Typographic Scales</h2><p>Typographic scales use ratios (mostly) borrowed from musical intervals. These ratios create "harmonious" proportions because they're based on the same mathematical relationships that make good music feel right.</p><p>Common scales:</p><ul><li>Minor Third (1.200) - Subtle</li>
<li>Major Third (1.250) - Balanced</li>
<li>Perfect Fourth (1.333) - Slightly more dramatic</li>
<li>Perfect Fifth (1.500) - Bold</li>
<li>Golden Ratio (1.618) - Not a musical interval, but commonly used</li>
</ul><p>These scales are exponential, not linear. Each heading level multiplies the previous level by the ratio, rather than adding to it.</p><div class="at-c-note"><p><strong>Exponential vs Linear:</strong> With a linear scale, each step adds the same fixed amount. With an exponential scale, each step multiplies by the ratio—so you get bigger jumps between larger sizes. That's why h1 is so much bigger than h2, which is bigger than h3, and so on, and so on, and so on.</p></div><p>Here's what that exponential growth looks like across heading levels with a Major Third scale (1.25):</p><figure class="at-c-codeblock"><pre>h6: 1rem × 1.25⁰ = 1rem
h5: 1rem × 1.25¹ = 1.25rem
h4: 1rem × 1.25² = 1.563rem
h3: 1rem × 1.25³ = 1.953rem
h2: 1rem × 1.25⁴ = 2.441rem
h1: 1rem × 1.25⁵ = 3.052rem
</pre></figure><p>The pattern, base-size × ratio ^ exponent.</p><p>This is where <code>pow()</code> comes in.</p><h2 id="enter-pow()%3A-exponentiation-in-css" tabindex="-1">Enter pow(): Exponentiation in CSS</h2><p>The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/pow"><code>pow()</code> function</a> is part of <a href="https://www.w3.org/TR/css-values-4/">CSS Values and Units Level 4</a>. It calculates a number raised to a power (<a href="https://en.wikipedia.org/wiki/Exponentiation">exponentiation</a>) in CSS.</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">pow(base, exponent)</pre></figure><p>For example:</p><ul><li><code>pow(2, 3) = 2³ = 8</code></li>
<li><code>pow(1.25, 4) = 1.25⁴ = 2.441</code></li>
</ul><p>This is exactly what we need to help calculate typographic scales. Instead of manually computing 1.25 × 1.25 × 1.25 × 1.25, we can write <code>pow(1.25, 4)</code>.</p><h2 id="the-missing-piece%3A-sibling-index()" tabindex="-1">The Missing Piece: sibling-index()</h2><p>Here's how it works in the ideal case. The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/sibling-index"><code>sibling-index()</code> function</a> returns the position of an element among its siblings, starting from 1 (it works with any elements, not just <code>:heading</code>).</p><p>In a typical demo where <code>h1</code> through <code>h6</code> are siblings in order, that index lines up with the heading level:</p><ul><li>h1 has <code>sibling-index() = 1</code></li>
<li>h2 has <code>sibling-index() = 2</code></li>
<li>h3 has <code>sibling-index() = 3</code></li>
<li>And so on...</li>
</ul><p>This means we can use <code>sibling-index()</code> to calculate the size dynamically for each heading level.</p><h2 id="putting-it-all-together" tabindex="-1">Putting It All Together</h2><p>Here's the full pattern in action:</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">:root {
  --font-size-base: 1rem;
  --scale-major-third: 1.25;
  --typographic-scale: var(--scale-major-third);
}
:heading {
  font-size: calc(
    var(--font-size-base) * pow(var(--typographic-scale), 6 - sibling-index())
  );
}</pre></figure><p>That's it. Three custom properties and one font-size rule.</p><p>Let's break down what's happening. First, <code>6 - sibling-index()</code> calculates the exponent for each heading. For h1 (index 1) it becomes <code>6 - 1 = 5</code>, for h2 it becomes <code>6 - 2 = 4</code>, and for h6 it becomes <code>6 - 6 = 0</code>.</p><p>Next, <code>pow(var(--typographic-scale), ...)</code> raises the scale ratio to that exponent. With a 1.25 ratio, h1 becomes <code>pow(1.25, 5) = 3.052</code>, h2 becomes <code>pow(1.25, 4) = 2.441</code>, and h6 becomes <code>pow(1.25, 0) = 1</code>.</p><p>Finally, <code>var(--font-size-base) * ...</code> multiplies that result by the base size so the whole scale can move up or down together.</p><p>The result is that h1 is the largest, h6 is the base size, and everything in between follows the exponential scale perfectly.</p><p>If you want a one-line mental model, it's this: <strong>font-size = base-size x ratio^(6 - sibling-index())</strong>. With a Perfect Fourth scale (1.333), that gives you a range from h1 at 4.209rem down to h6 at 1rem, with each heading level stepping down by the same ratio.</p><h2 id="building-a-complete-scale-system" tabindex="-1">Building a Complete Scale System</h2><p>Let's expand this into a practical system with multiple scale options:</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">:root {
  /* Scale ratios based on musical intervals */
  --scale-minor-second: 1.067;
  --scale-major-second: 1.125;
  --scale-minor-third: 1.2;
  --scale-major-third: 1.25;
  --scale-perfect-fourth: 1.333;
  --scale-augmented-fourth: 1.414;
  --scale-perfect-fifth: 1.5;
  --scale-golden-ratio: 1.618;
  /* Active scale - change this to switch globally */
  --typographic-scale: var(--scale-major-third);
  /* Base size and max level for clarity */
  --heading-base-size: 1rem;
  --heading-max-level: 6;
}
:heading {
  font-size: calc(
    var(--heading-base-size) *
      pow(var(--typographic-scale), var(--heading-max-level) - sibling-index())
  );
}</pre></figure><p>Now you can experiment with different scales by changing a single variable. Want to try a Perfect Fourth scale? Just update <code>--typographic-scale</code>:</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">:root {
  --typographic-scale: var(--scale-perfect-fourth);
}</pre></figure><p>Every heading on your site instantly updates to the new scale.</p><p>You can also nudge the overall size up or down by adjusting <code>--heading-base-size</code>.</p><h2 id="responsive-typography" tabindex="-1">Responsive Typography</h2><p>Several years ago I attended an amazing workshop from <a href="https://clagnut.com">Rich</a> on responsive web typography, and one thing stuck with me. You don't have to use the same scale across all devices. Narrow viewports can use a tighter scale, while larger viewports can breathe a little more. Using the system we've created, we can adjust the scale based on viewport size.</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">:root {
  --typographic-scale: var(--scale-minor-third);
}
/* Smaller scale on mobile to prevent oversized headings */
@media (width &gt;= 768px) {
  :root {
    --typographic-scale: var(--scale-major-third);
  }
}
/* Larger scale on big screens where you have more space */
@media (width &gt;= 1400px) {
  :root {
    --typographic-scale: var(--scale-perfect-fourth);
  }
}</pre></figure><p>Here's how you might structure this in a real design system:</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">:root {
  /* Color tokens */
  --color-heading: #2c3e50;
  --color-heading-secondary: #546e7a;
  /* Typography scales */
  --scale-minor-third: 1.2;
  --scale-major-third: 1.25;
  --scale-perfect-fourth: 1.333;
  --scale-augmented-fourth: 1.414;
  --scale-perfect-fifth: 1.5;
  --scale-golden-ratio: 1.618;
  /* Active scale */
  --typographic-scale: var(--scale-minor-third);
  /* Base values */
  --heading-base-size: 0.9375rem;
  --heading-max-level: 6;
  --heading-font-weight: 600;
  --heading-font-weight--strong: 700;
  --heading-line-height: 1.2;
  --heading-letter-spacing: -0.02em;
  --heading-letter-spacing--tight: -0.03em;
  --heading-letter-spacing--loose: -0.01em;
  --heading-letter-spacing--caps: 0.05em;
  /* Spacing */
  --spacing-heading-block: 1.5rem 0.5rem;
}
/* Base heading styles */
:heading {
  font-size: calc(
    var(--heading-base-size) *
      pow(var(--typographic-scale), var(--heading-max-level) - sibling-index())
  );
  font-family: var(--font-family-heading, 'Georgia', serif);
  font-weight: var(--heading-font-weight);
  line-height: var(--heading-line-height);
  letter-spacing: var(--heading-letter-spacing);
  color: var(--color-heading);
  margin-block: var(--spacing-heading-block);
  word-wrap: break-word;
}
/* Tiered weights */
:heading(1, 2, 3) {
  --heading-font-weight: var(--heading-font-weight--strong);
  --heading-letter-spacing: var(--heading-letter-spacing--tight);
}
:heading(4, 5, 6) {
  --heading-font-weight: var(--heading-font-weight);
  --heading-letter-spacing: var(--heading-letter-spacing--loose);
  color: var(--color-heading-secondary);
}
/* Special case for h6 */
:heading(6) {
  text-transform: uppercase;
  --heading-letter-spacing: var(--heading-letter-spacing--caps);
}
/* Responsive adjustments */
@media (width &gt;= 768px) {
  :root {
    --typographic-scale: var(--scale-major-third);
    --heading-base-size: 1rem;
  }
}
@media (width &gt;= 1400px) {
  :root {
    --typographic-scale: var(--scale-perfect-fourth);
  }
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
  :root {
    --color-heading: #ecf0f1;
    --color-heading-secondary: #bdc3c7;
  }
}</pre></figure><div class="at-c-note"><p>This follows Mike's <a href="https://www.smashingmagazine.com/2018/05/css-custom-properties-strategy-guide/">cascading custom property strategy</a>, so css custom properties can be overridden contextually without duplicating rules.</p></div><p>This gives you a complete, flexible, maintainable heading system. It keeps mathematical precision for sizing, adapts to different contexts, responds to viewport size, supports theming, and can be updated globally with a single variable change.</p><h2 id="what-works-in-real-layouts" tabindex="-1">What Works in Real Layouts</h2><p>If you want the scale to work even when headings repeat or skip levels, you can assign the level explicitly and keep the maths intact. This removes the dependency on sibling order.</p><figure class="at-c-codeblock"><figcaption class="at-c-codeblock-language">Code languagecss</figcaption><pre class="language-css">:root {
  --heading-base-size: 1rem;
  --typographic-scale: 1.25; /* Major Third */
}
:heading {
  font-size: calc(
    var(--heading-base-size) *
      pow(var(--typographic-scale), var(--heading-level))
  );
}
:heading(1) {
  --heading-level: 5;
}
:heading(2) {
  --heading-level: 4;
}
:heading(3) {
  --heading-level: 3;
}
:heading(4) {
  --heading-level: 2;
}
:heading(5) {
  --heading-level: 1;
}
:heading(6) {
  --heading-level: 0;
}</pre></figure><p>It’s a few more lines, but it behaves correctly no matter how your headings are ordered in the markup.</p><h2 id="why-this-matters" tabindex="-1">Why This Matters</h2><p>This approach nudges how we think about CSS. Instead of declaring individual values, we're defining systems and letting CSS calculate the details.</p><p>Values update based on context, viewport, and user preferences. The mathematical relationship is expressed once and applied everywhere. Want to try a different scale? Change one variable. Want to adjust all heading sizes? Change the base size. The relationships remain consistent.</p><h2 id="browser-support-and-testing" tabindex="-1">Browser Support and Testing</h2><p>Safari Technology Preview is currently the only browser that supports all three features used here.</p><p>If you want to track progress or add support signals, here are the two issues to star or follow:</p><ul><li><a href="https://issues.chromium.org/issues/438147580"><code>:heading</code> (Chrome)</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1953973"><code>sibling-index()</code> (Firefox)</a></li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=296994"><code>:heading</code> and <code>heading()</code> (Safari)</a></li>
</ul><h2 id="wrapping-up" tabindex="-1">Wrapping Up</h2><p>The combination of <code>:heading()</code>, <code>sibling-index()</code>, and <code>pow()</code> can transform typographic scales from a tedious process into an elegant, mathematical system.</p><p>You define the rules once, and CSS handles the calculations.</p><p>This is more than a convenience feature.</p><p>It's a glimpse into a future where we can express design systems as mathematical relationships rather than exhaustive declarations. The code becomes more maintainable and more flexible.</p><p>
<a class="at-bluesky-likes__cta" href="#" target="_blank" data-bsky-post-link="" rel="nofollow noopener">Like this post on Bluesky</a></p>]]></description>
      <link>https://www.alwaystwisted.com/articles/building-typographic-scales-with-headings-sibling-index-and-pow</link>
      <guid>https://www.alwaystwisted.com/articles/building-typographic-scales-with-headings-sibling-index-and-pow</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[OpenSpec — A lightweight spec‑driven framework]]></title>
      <description><![CDATA[<div class="tab-panel active" data-panel="spec-deltas" data-astro-cid-vnivfuh2=""><p>Review intent, not just code</p><p>Each OpenSpec change produces a spec delta that captures the change in requirements of the system. This makes it easy for developers to understand how they're modifying the system and what will need to change. It also allows reviewers to understand the change itself without having to dig through the code and quickly gain a high level understanding.</p><div class="file-block" data-astro-cid-vnivfuh2=""><p>openspec/specs/auth-session/spec.md</p><div class="file-content" data-astro-cid-vnivfuh2=""><p>### Requirement: Session expiration</p><p>- The system SHALL expire sessions after a configured duration.</p><p>+ The system SHALL support configurable session expiration periods.</p><p>#### Scenario: Default session timeout</p><p>- GIVEN a user has authenticated</p><p>- - WHEN 24 hours pass without activity</p><p>+ - WHEN 24 hours pass without "Remember me"</p><p>- THEN invalidate the session token</p><p>+ #### Scenario: Extended session with remember me</p><p>+ - GIVEN user checks "Remember me" at login</p><p>+ - WHEN 30 days have passed</p><p>+ - THEN invalidate the session token</p><p>+ - AND clear the persistent cookie</p></div></div></div><div class="tab-panel" data-panel="spec-library" data-astro-cid-vnivfuh2=""><p>Context that persists</p><p>Your specs live in the repository alongside your code, organized by capability. When an agent needs context about how a feature should work, it reads the spec. When a new developer joins, they can browse the library to understand the system. Context doesn't disappear when a chat session ends or someone leaves the team.</p><div class="spec-preview-container" data-astro-cid-vnivfuh2=""><div class="file-block spec-tree" data-astro-cid-vnivfuh2=""><p>$ tree openspec/specs/</p><div class="file-content" data-astro-cid-vnivfuh2=""><p>openspec/specs/</p><p>├── auth-login/</p><p>│ └── spec.md</p><p>├── auth-session/</p><p>│ └── spec.md</p><p>├── checkout-cart/</p><p>│ └── spec.md</p><p>└── checkout-payment/</p><p>    └── spec.md</p></div></div><div class="file-block spec-preview" data-astro-cid-vnivfuh2=""><p>openspec/specs/auth-session/spec.md</p><div class="file-content" data-astro-cid-vnivfuh2=""><p># auth-session Specification</p><p>## Purpose</p><p>Manage user session lifecycle including creation, validation, and expiration.</p><p>## Requirements</p><p>### Requirement: Session expiration</p><p>The system SHALL expire sessions after a configured duration.</p><p>#### Scenario: Default session timeout</p><p>- GIVEN a user has authenticated</p><p>- WHEN 24 hours pass without activity</p><p>- THEN invalidate the session token</p><p>- AND require re-authentication</p></div></div></div></div><div class="tab-panel" data-panel="change-proposal" data-astro-cid-vnivfuh2=""><p>Something to review in seconds</p><p>When you describe a change you want to make, OpenSpec generates everything needed to review it: a proposal document, broken-down implementation tasks, technical design decisions, and the spec deltas showing how requirements will change. You review and refine the plan before any code is written, catching misalignment early.</p><div class="agent-container" data-astro-cid-vnivfuh2=""><p>agent</p><p>&gt; /openspec:proposal Add remember me checkbox with 30-day sessions</p><div class="agent-output" data-astro-cid-vnivfuh2=""><p>Searching existing specs for authentication requirements...</p><p>Read(openspec/specs/auth-session/spec.md)</p><p>Searching existing codebase for session handling...</p><p>Read(src/auth/session.ts)</p><p>Creating proposal and breaking down implementation tasks...</p><p>Created change proposal with ID add-remember-me</p><div class="agent-tree" data-astro-cid-vnivfuh2=""><p>openspec/changes/add-remember-me/</p><p>├── proposal.md ← describe the change</p><p>├── design.md ← technical decisions</p><p>├── tasks.md ← implementation tasks</p><p>└── specs/ ← spec deltas</p><p>    └── auth-session/</p><p>        └── spec.md</p></div></div></div><p>This change affects 1 spec, with 3 phases and 8 tasks</p></div>]]></description>
      <link>https://openspec.dev/</link>
      <guid>https://openspec.dev/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Gervais Principle]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.ribbonfarm.com/2009/10/07/the-gervais-principle-or-the-office-according-to-the-office/</link>
      <guid>https://www.ribbonfarm.com/2009/10/07/the-gervais-principle-or-the-office-according-to-the-office/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[joshcirre/instruckt-laravel]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">instruckt-laravel</h1><a id="user-content-instruckt-laravel" class="anchor" aria-label="Permalink: instruckt-laravel" href="#instruckt-laravel"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Laravel package for <a href="https://github.com/joshcirre/instruckt">instruckt</a> — visual feedback for AI coding agents. Provides the backend API, MCP tools, JSON file storage, and a Blade toolbar component.</p>
<p dir="auto">Users annotate elements in the browser, annotations are copied as structured markdown, and your AI agent can also read them via MCP.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Requirements</h2><a id="user-content-requirements" class="anchor" aria-label="Permalink: Requirements" href="#requirements"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li>PHP 8.2+</li>
<li>Laravel 11 or 12</li>
<li><a href="https://github.com/laravel/mcp">laravel/mcp</a> (optional, for MCP tool integration)</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Install</h2><a id="user-content-install" class="anchor" aria-label="Permalink: Install" href="#install"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="composer require joshcirre/instruckt-laravel --dev"><pre>composer require joshcirre/instruckt-laravel --dev</pre></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="php artisan instruckt:install"><pre>php artisan instruckt:install</pre></div>
<p dir="auto">This publishes the config, copies the JS assets, and automatically configures MCP for any detected AI agents (Claude Code, Cursor, Codex, OpenCode, GitHub Copilot).</p>
<p dir="auto">To uninstall, run <code>php artisan instruckt:uninstall</code>. See <a href="#uninstall">Uninstall</a> for details.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Setup</h2><a id="user-content-setup" class="anchor" aria-label="Permalink: Setup" href="#setup"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The install command auto-detects your JS entry point and adds a dev-only import:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// Instruckt — visual feedback toolbar (only loaded in dev)
if (import.meta.env.DEV) {
    import('instruckt').then(({ Instruckt }) =&gt; new Instruckt({ endpoint: '/instruckt' }));
}"><pre><span class="pl-c">// Instruckt — visual feedback toolbar (only loaded in dev)</span>
<span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-k">import</span><span class="pl-kos">.</span>meta<span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">DEV</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">import</span><span class="pl-kos">(</span><span class="pl-s">'instruckt'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">{</span> Instruckt <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-k">new</span> <span class="pl-v">Instruckt</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">endpoint</span>: <span class="pl-s">'/instruckt'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This uses Vite's <code>import.meta.env.DEV</code> flag, which means:</p>
<ul dir="auto">
<li><strong><code>bun run dev</code> / <code>npm run dev</code></strong> — toolbar loads normally</li>
<li><strong><code>bun run build</code> / <code>npm run build</code></strong> — instruckt is completely tree-shaken out of the production bundle (zero bytes shipped)</li>
</ul>
<p dir="auto">This works for <strong>all frameworks</strong> — Livewire, Inertia (Vue/React/Svelte), or plain Blade — since Laravel apps already have a Vite JS entrypoint.</p>
<blockquote>
<p dir="auto"><strong>Alternative: Blade component</strong> — If you prefer not to touch your JS files, you can use <code>&lt;x-instruckt-toolbar /&gt;</code> in your layout instead. See <a href="#toolbar-component">Toolbar Component</a> below.</p>
</blockquote>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Manual Setup</h3><a id="user-content-manual-setup" class="anchor" aria-label="Permalink: Manual Setup" href="#manual-setup"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you need to add the import manually (or the install command didn't detect your entry point), add this to your <code>resources/js/app.js</code> (or <code>.ts</code>, <code>.tsx</code>, <code>.jsx</code>):</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="if (import.meta.env.DEV) {
    import('instruckt').then(({ Instruckt }) =&gt; new Instruckt({ endpoint: '/instruckt' }));
}"><pre><span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-k">import</span><span class="pl-kos">.</span>meta<span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">DEV</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">import</span><span class="pl-kos">(</span><span class="pl-s">'instruckt'</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">{</span> Instruckt <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-k">new</span> <span class="pl-v">Instruckt</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">endpoint</span>: <span class="pl-s">'/instruckt'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Connect Your AI Agent</h3><a id="user-content-connect-your-ai-agent" class="anchor" aria-label="Permalink: Connect Your AI Agent" href="#connect-your-ai-agent"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The install command automatically detects your AI agent and configures MCP. If you need to do it manually, add to <code>.mcp.json</code> (Claude Code):</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;mcpServers&quot;: {
    &quot;instruckt&quot;: {
      &quot;command&quot;: &quot;php&quot;,
      &quot;args&quot;: [&quot;artisan&quot;, &quot;mcp:start&quot;, &quot;instruckt&quot;]
    }
  }
}"><pre>{
  <span class="pl-ent">"mcpServers"</span>: {
    <span class="pl-ent">"instruckt"</span>: {
      <span class="pl-ent">"command"</span>: <span class="pl-s"><span class="pl-pds">"</span>php<span class="pl-pds">"</span></span>,
      <span class="pl-ent">"args"</span>: [<span class="pl-s"><span class="pl-pds">"</span>artisan<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>mcp:start<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>instruckt<span class="pl-pds">"</span></span>]
    }
  }
}</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Storage</h2><a id="user-content-storage" class="anchor" aria-label="Permalink: Storage" href="#storage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Annotations are stored in <code>storage/app/_instruckt/annotations.json</code>. Screenshots are saved as PNGs in <code>storage/app/_instruckt/screenshots/</code>. No database migrations needed.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">MCP Tools</h2><a id="user-content-mcp-tools" class="anchor" aria-label="Permalink: MCP Tools" href="#mcp-tools"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The package registers these MCP tools for your AI agent:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Tool</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>instruckt.get_all_pending</code></td>
<td>Get all pending annotations</td>
</tr>
<tr>
<td><code>instruckt.get_screenshot</code></td>
<td>Get the screenshot image for an annotation</td>
</tr>
<tr>
<td><code>instruckt.resolve</code></td>
<td>Mark an annotation as resolved (removes marker from browser)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Configuration</h2><a id="user-content-configuration" class="anchor" aria-label="Permalink: Configuration" href="#configuration"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Publish the config file to customize:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="php artisan vendor:publish --tag=instruckt-config"><pre>php artisan vendor:publish --tag=instruckt-config</pre></div>
<p dir="auto">Published to <code>config/instruckt.php</code>:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="return [
    // Only enabled in local env by default
    'enabled' =&gt; (bool) env('INSTRUCKT_ENABLED', env('APP_ENV') === 'local'),

    // API route prefix
    'route_prefix' =&gt; env('INSTRUCKT_ROUTE_PREFIX', 'instruckt'),

    // Middleware applied to API routes
    'middleware' =&gt; explode(',', env('INSTRUCKT_MIDDLEWARE', 'api')),

    // Override JS source (e.g. pinned CDN version)
    'cdn_url' =&gt; env('INSTRUCKT_CDN_URL', null),

    // Marker pin colors (CSS color strings)
    'colors' =&gt; [
        // 'default'    =&gt; '#6366f1',  // indigo — standard annotations
        // 'screenshot' =&gt; '#22c55e',  // green — annotations with screenshots
        // 'dismissed'  =&gt; '#71717a',  // gray — dismissed
    ],

    // Keyboard shortcuts (single key characters)
    'keys' =&gt; [
        // 'annotate'   =&gt; 'a',  // toggle annotation mode
        // 'freeze'     =&gt; 'f',  // freeze page
        // 'screenshot' =&gt; 'c',  // region screenshot capture
        // 'clearPage'  =&gt; 'x',  // clear current page
    ],
];"><pre><span class="pl-k">return</span> [
    <span class="pl-c">// Only enabled in local env by default</span>
    <span class="pl-s">'<span class="pl-s">enabled</span>'</span> =&gt; (<span class="pl-smi">bool</span>) <span class="pl-en">env</span>(<span class="pl-s">'<span class="pl-s">INSTRUCKT_ENABLED</span>'</span>, <span class="pl-en">env</span>(<span class="pl-s">'<span class="pl-s">APP_ENV</span>'</span>) === <span class="pl-s">'<span class="pl-s">local</span>'</span>),

    <span class="pl-c">// API route prefix</span>
    <span class="pl-s">'<span class="pl-s">route_prefix</span>'</span> =&gt; <span class="pl-en">env</span>(<span class="pl-s">'<span class="pl-s">INSTRUCKT_ROUTE_PREFIX</span>'</span>, <span class="pl-s">'<span class="pl-s">instruckt</span>'</span>),

    <span class="pl-c">// Middleware applied to API routes</span>
    <span class="pl-s">'<span class="pl-s">middleware</span>'</span> =&gt; <span class="pl-en">explode</span>(<span class="pl-s">'<span class="pl-s">,</span>'</span>, <span class="pl-en">env</span>(<span class="pl-s">'<span class="pl-s">INSTRUCKT_MIDDLEWARE</span>'</span>, <span class="pl-s">'<span class="pl-s">api</span>'</span>)),

    <span class="pl-c">// Override JS source (e.g. pinned CDN version)</span>
    <span class="pl-s">'<span class="pl-s">cdn_url</span>'</span> =&gt; <span class="pl-en">env</span>(<span class="pl-s">'<span class="pl-s">INSTRUCKT_CDN_URL</span>'</span>, <span class="pl-c1">null</span>),

    <span class="pl-c">// Marker pin colors (CSS color strings)</span>
    <span class="pl-s">'<span class="pl-s">colors</span>'</span> =&gt; [
        <span class="pl-c">// 'default'    =&gt; '#6366f1',  // indigo — standard annotations</span>
        <span class="pl-c">// 'screenshot' =&gt; '#22c55e',  // green — annotations with screenshots</span>
        <span class="pl-c">// 'dismissed'  =&gt; '#71717a',  // gray — dismissed</span>
    ],

    <span class="pl-c">// Keyboard shortcuts (single key characters)</span>
    <span class="pl-s">'<span class="pl-s">keys</span>'</span> =&gt; [
        <span class="pl-c">// 'annotate'   =&gt; 'a',  // toggle annotation mode</span>
        <span class="pl-c">// 'freeze'     =&gt; 'f',  // freeze page</span>
        <span class="pl-c">// 'screenshot' =&gt; 'c',  // region screenshot capture</span>
        <span class="pl-c">// 'clearPage'  =&gt; 'x',  // clear current page</span>
    ],
];</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Toolbar Component (Alternative)</h2><a id="user-content-toolbar-component-alternative" class="anchor" aria-label="Permalink: Toolbar Component (Alternative)" href="#toolbar-component-alternative"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you'd rather not add a JS import, you can use the Blade component. Add it to your layout(s) before <code>&lt;/body&gt;</code>:</p>
<div class="highlight highlight-text-html-php-blade notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;x-instruckt-toolbar /&gt;"><pre>&lt;<span class="pl-ent">x-instruckt-toolbar</span> /&gt;</pre></div>
<p dir="auto">The component is automatically gated behind <code>config('instruckt.enabled')</code>, which defaults to <code>true</code> only when <code>APP_ENV=local</code>. It won't render anything in production — no extra checks needed.</p>
<p dir="auto">The component loads the IIFE build and accepts optional attributes:</p>
<div class="highlight highlight-text-html-php-blade notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;x-instruckt-toolbar
    theme=&quot;dark&quot;
    position=&quot;bottom-left&quot;
    :adapters=&quot;['livewire', 'vue']&quot;
    :colors=&quot;['default' =&gt; '#6366f1', 'screenshot' =&gt; '#22c55e', 'dismissed' =&gt; '#71717a']&quot;
    :keys=&quot;['annotate' =&gt; 'a', 'freeze' =&gt; 'f']&quot;
/&gt;"><pre>&lt;<span class="pl-ent">x-instruckt-toolbar</span>
    <span class="pl-e">theme</span>=<span class="pl-s"><span class="pl-pds">"</span>dark<span class="pl-pds">"</span></span>
    <span class="pl-e">position</span>=<span class="pl-s"><span class="pl-pds">"</span>bottom-left<span class="pl-pds">"</span></span>
    <span class="pl-e">:adapters</span>=<span class="pl-s"><span class="pl-pds">"</span>['livewire', 'vue']<span class="pl-pds">"</span></span>
    <span class="pl-e">:colors</span>=<span class="pl-s"><span class="pl-pds">"</span>['default' =&gt; '#6366f1', 'screenshot' =&gt; '#22c55e', 'dismissed' =&gt; '#71717a']<span class="pl-pds">"</span></span>
    <span class="pl-e">:keys</span>=<span class="pl-s"><span class="pl-pds">"</span>['annotate' =&gt; 'a', 'freeze' =&gt; 'f']<span class="pl-pds">"</span></span>
/&gt;</pre></div>
<p dir="auto">You can also set colors and keys globally via <code>config/instruckt.php</code> instead of passing them as component attributes.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Production Safety</h2><a id="user-content-production-safety" class="anchor" aria-label="Permalink: Production Safety" href="#production-safety"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Instruckt is designed as a dev-only tool with multiple layers of protection:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Layer</th>
<th>JS Method</th>
<th>Blade Method</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Frontend</strong></td>
<td><code>import.meta.env.DEV</code> — code is tree-shaken out of production Vite builds entirely</td>
<td><code>@if(config('instruckt.enabled'))</code> — component doesn't render</td>
</tr>
<tr>
<td><strong>Backend routes</strong></td>
<td>Only registered when <code>config('instruckt.enabled')</code> is <code>true</code></td>
<td>Same</td>
</tr>
<tr>
<td><strong>Middleware</strong></td>
<td>Only active when enabled</td>
<td>Same</td>
</tr>
<tr>
<td><strong>Config default</strong></td>
<td><code>enabled</code> defaults to <code>true</code> only when <code>APP_ENV=local</code></td>
<td>Same</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">Even if you accidentally install instruckt as a non-dev Composer dependency, the toolbar won't appear in production as long as you build your assets with <code>vite build</code> (JS method) or have <code>APP_ENV=production</code> (Blade method).</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">How It Works</h2><a id="user-content-how-it-works" class="anchor" aria-label="Permalink: How It Works" href="#how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>The JS import (or Blade component) initializes the annotation UI</li>
<li>Users click elements and leave feedback — optionally capturing screenshots</li>
<li>Annotations auto-copy as structured markdown to the clipboard for pasting into AI agents</li>
<li>Annotations are persisted to <code>storage/app/_instruckt/</code> via API routes</li>
<li>On page reload (including Vite rebuilds), annotations are loaded from the API and markers reappear</li>
<li>AI agents can read pending annotations via MCP tools and resolve them after fixing</li>
</ol>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">API Routes</h2><a id="user-content-api-routes" class="anchor" aria-label="Permalink: API Routes" href="#api-routes"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">All routes are registered under the configured prefix (default: <code>/instruckt</code>):</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Method</th>
<th>Route</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>GET</td>
<td><code>/instruckt/annotations</code></td>
<td>List all annotations</td>
</tr>
<tr>
<td>POST</td>
<td><code>/instruckt/annotations</code></td>
<td>Create annotation</td>
</tr>
<tr>
<td>PATCH</td>
<td><code>/instruckt/annotations/{id}</code></td>
<td>Update annotation</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Keyboard Shortcuts</h2><a id="user-content-keyboard-shortcuts" class="anchor" aria-label="Permalink: Keyboard Shortcuts" href="#keyboard-shortcuts"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Default shortcuts (customizable via <code>keys</code> config):</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Key</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>A</code></td>
<td>Toggle annotation mode</td>
</tr>
<tr>
<td><code>F</code></td>
<td>Toggle freeze animations</td>
</tr>
<tr>
<td><code>C</code></td>
<td>Screenshot region capture</td>
</tr>
<tr>
<td><code>X</code></td>
<td>Clear annotations on current page</td>
</tr>
<tr>
<td><code>Esc</code></td>
<td>Exit annotation/freeze mode</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Secure Context Note</h2><a id="user-content-secure-context-note" class="anchor" aria-label="Permalink: Secure Context Note" href="#secure-context-note"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>navigator.clipboard</code> requires a secure context (HTTPS or localhost). On <code>http://*.test</code> domains, auto-copy on annotation submit is skipped. Use the copy button in the toolbar which uses a fallback method.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Uninstall</h2><a id="user-content-uninstall" class="anchor" aria-label="Permalink: Uninstall" href="#uninstall"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">To cleanly remove instruckt from your project:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="php artisan instruckt:uninstall"><pre>php artisan instruckt:uninstall</pre></div>
<p dir="auto">This scans for all instruckt artifacts, shows you what will be removed, and asks for confirmation before proceeding. It reverses everything the install command did:</p>
<ul dir="auto">
<li>Published config (<code>config/instruckt.php</code>)</li>
<li>JS toolbar code from your entry point (<code>resources/js/app.js</code>, etc.)</li>
<li>Blade toolbar component from layout files</li>
<li>MCP server entries from all agent configs (<code>.mcp.json</code>, <code>.cursor/mcp.json</code>, etc.)</li>
<li>Agent skill directories</li>
<li>Stored annotations and screenshots (<code>storage/app/instruckt/</code>)</li>
<li>The <code>instruckt</code> npm package</li>
</ul>
<p dir="auto">After uninstalling, remove the Composer package:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="composer remove joshcirre/instruckt-laravel --dev"><pre>composer remove joshcirre/instruckt-laravel --dev</pre></div>
<p dir="auto">Options:</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Flag</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--force</code></td>
<td>Skip the confirmation prompt</td>
</tr>
<tr>
<td><code>--keep-config</code></td>
<td>Keep <code>config/instruckt.php</code></td>
</tr>
<tr>
<td><code>--keep-npm</code></td>
<td>Keep the npm package installed</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT</p>
</article></div>]]></description>
      <link>https://github.com/joshcirre/instruckt-laravel?tab=readme-ov-file</link>
      <guid>https://github.com/joshcirre/instruckt-laravel?tab=readme-ov-file</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The 8 Levels of Agentic Engineering — Bassim Eledath]]></title>
      <description><![CDATA[<p>AI's coding ability is outpacing our ability to wield it effectively. That's why all the SWE-bench score maxxing isn't syncing with the productivity metrics engineering leadership actually cares about. When Anthropic's team ships a product like Cowork in 10 days and another team can't move past a broken POC using the same models, the difference is that one team has closed the gap between capability and practice and the other hasn't.</p><p>That gap doesn't close overnight. It closes in levels. 8 of them. Most of you reading this are likely past the first few, and you should be eager to reach the next one because each subsequent level is a huge leap in output, and every improvement in model capability amplifies those gains further.</p><p>The other reason you should care is the multiplayer effect. Your output depends more than you'd think on the level of your teammates. Say you're a level 7 wizard, raising several solid PRs with your background agents while you sleep. If your repo requires a colleague's approval before merge, and that colleague is on level 2, still manually reviewing PRs, that stifles your throughput. So it is in your best interest to pull your team up.</p><p>From talking to several teams and individuals practicing AI-assisted coding, here's the progression of levels I've seen play out, imperfectly sequential:</p><div><figure class="my-6"><img alt="The 8 Levels of Agentic Engineering" width="800" height="450" data-nimg="1" class="rounded-lg c1" sizes="(max-width: 768px) 100vw, 72ch" srcset="/_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=640&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 640w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=750&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 750w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=828&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 828w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=1080&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1080w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=1200&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1200w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=1920&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1920w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=2048&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 2048w, /_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 3840w" src="https://www.bassimeledath.com/_next/image?url=%2Fimages%2Fblog%2Flevels-agentic-eng.jpg&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT" /><figcaption class="mt-2 text-center text-sm text-muted">The 8 Levels of Agentic Engineering</figcaption></figure></div><p>I'll address these two zippily, mostly for posterity. Skim freely.</p><p>Tab completion is where it started. GitHub Copilot kicked off the movement. Click tab, autocomplete code. Probably long forgotten by many and skipped entirely by new entrants to agentic engineering. It favored experienced devs who could adeptly skeleton their code before AI filled in the blanks.</p><p>AI-focused IDEs like Cursor changed the game by connecting chat to your codebase, making multi-file edits dramatically easier. But the ceiling was always context. The model could only help with what it could see, and annoyingly often, it was either not seeing the right context or seeing too much of the wrong context.</p><p>Most people at this level are also experimenting with plan mode in their coding agent of choice: translating a rough idea into a structured step-by-step plan for the LLM, iterating on that plan, and then triggering the implementation. It works well at this stage, and it's a reasonable way to maintain control. Though we'll see in later levels less of a dependence on plan mode.</p><p>Now the fun stuff. Buzz phrase of the year in 2025, context engineering became a thing when models got reliably good at following a reasonable number of instructions with just the right amount of context. Noisy context was just as bad as underspecified context, so the effort was in improving the information density of each token. "Every token needs to fight for its place in the prompt" was the mantra.</p><div><figure class="my-6"><img alt="Same message, fewer tokens — information density was the name of the game (source: humanlayer/12-factor-agents)" width="800" height="450" data-nimg="1" class="rounded-lg c1" sizes="(max-width: 768px) 100vw, 72ch" srcset="/_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=640&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 640w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=750&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 750w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=828&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 828w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=1080&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1080w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=1200&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1200w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=1920&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1920w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=2048&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 2048w, /_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 3840w" src="https://www.bassimeledath.com/_next/image?url=%2Fimages%2Fblog%2Fcontext-eng.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT" /><figcaption class="mt-2 text-center text-sm text-muted">Same message, fewer tokens — information density was the name of the game (source: humanlayer/12-factor-agents)</figcaption></figure></div><p>In practice, context engineering touches more surface area than people realize. It's your system prompt and rules files (<code>.cursorrules</code>, <code>CLAUDE.md</code>). It's how you describe your tools, because the model reads those descriptions to decide which ones to call. It's managing conversation history so a long-running agent doesn't lose the plot ten turns in. It's deciding which tools to even expose per turn, because too many options overwhelm the model just like they overwhelm people.</p><p>You don't hear as much about context engineering these days. The scale has tipped in favor of models that forgive noisier context and reason through messier terrain (larger context windows help too). Still, being mindful of what eats up context remains relevant. A few examples of where it still bites:</p><ul><li><strong>Smaller models are more context-sensitive.</strong> Voice applications often use smaller models, and context size also correlates with time to first token, which affects latency.</li>
<li><strong>Token-heavy tools and modalities.</strong> MCPs like Playwright and image inputs burn through tokens fast, pushing you into "compact session" state in Claude Code way sooner than you'd expect.</li>
<li><strong>Agents with access to dozens of tools,</strong> where the model spends more tokens parsing tool schemas than doing useful work.</li>
</ul><p>The broader point is that context engineering hasn't gone away, it's just evolved. The focus has shifted from filtering out bad context to making sure the right context is present at the right time. That shift is what sets up level 4.</p><p>Context engineering improves the current session. <a href="https://every.to/source-code/my-ai-had-already-fixed-the-code-before-i-saw-it" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Compounding engineering</a> improves every session after it. Popularized by Kieran Klaassen, compounding engineering was an inflection point for not only me but many others that "vibe coding" could do far more than just prototyping.</p><p>It's a plan, delegate, assess, codify loop. You plan the task with enough context for the LLM to succeed. You delegate it. You assess the output. And then, crucially, you codify what you learned: what worked, what broke, what pattern to follow next time.</p><div><figure class="my-6"><img alt="The compounding loop: plan, delegate, assess, codify — each cycle makes the next one better" width="800" height="450" data-nimg="1" class="rounded-lg c1" sizes="(max-width: 768px) 100vw, 72ch" srcset="/_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=640&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 640w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=750&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 750w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=828&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 828w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=1080&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1080w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=1200&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1200w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=1920&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1920w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=2048&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 2048w, /_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 3840w" src="https://www.bassimeledath.com/_next/image?url=%2Fimages%2Fblog%2Fcompounding-eng.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT" /><figcaption class="mt-2 text-center text-sm text-muted">The compounding loop: plan, delegate, assess, codify — each cycle makes the next one better</figcaption></figure></div><p>The magic is in that codify step. LLMs are stateless. If they re-introduce a dependency you explicitly removed yesterday, they'll do it again tomorrow unless you tell them not to. The most common way to close that loop is updating your <code>CLAUDE.md</code> (or equivalent rules file) so the lesson is baked into every future session. A word of caution: the instinct to codify everything into your rules file can backfire (too many instructions is as good as none). The better move is to create a setting where the LLM can easily discover useful context on its own, for example by maintaining an up-to-date <code>docs/</code> folder (more on this in Level 7).</p><p>Practitioners of compounding engineering are usually hyper-aware of the context being fed to their LLM. When an LLM makes a mistake, they instinctively think about missing context before blaming the model's competence. That instinct is what makes levels 5 through 8 possible.</p><p>Levels 3 and 4 solve for context. Level 5 solves for capability. MCPs and custom skills give your LLM access to your database, your APIs, your CI pipeline, your design system, Playwright for browser testing, Slack for notifications. Instead of just thinking about your codebase, the model can now act on it.</p><p>There's no shortage of good material on MCPs and skills already, so I won't rehash what they are. But here are some examples of how I use them: my team shares a PR review skill that we've all iterated on (and still do) that conditionally launches subagents depending on the nature of the PR. One handles integration safety with the database. Another runs complexity analysis to flag redundancies or overengineering. Another checks prompt health to ensure our prompts follow the team's standard format. It also runs linters and Ruff.</p><p>Why invest this much in a review skill? Because as agents start producing PRs at volume, human review becomes the bottleneck, not the quality gate. Latent Space makes a <a href="https://www.latent.space/p/reviews-dead" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">compelling case</a> that code review as we know it is dead. Automated, consistent, skill-driven review is what replaces it.</p><p>On the MCP side, I use the Braintrust MCP so my LLM can query evaluation logs and make changes directly. I use DeepWiki MCP to give my agent access to documentation for any open-source repo without manually pulling it into context.</p><p>Once multiple people on your team are writing their own versions of the same skill, it's worth consolidating into a shared registry. <a href="https://engineering.block.xyz/blog/3-principles-for-designing-agent-skills" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Block</a> (my condolences) has a great write-up on this: they built an internal skills marketplace with over 100 skills and curated bundles for specific roles and teams. Skills get the same treatment as code: pull requests, reviews, version history.</p><p>One more trend worth calling out: it's becoming common for LLMs to use CLI tools instead of MCPs (and it seems like every company is shipping one: <a href="https://justin.poehnelt.com/posts/rewrite-your-cli-for-ai-agents/" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Google Workspace CLI</a>, Braintrust is launching one soon). The reason is token efficiency. MCP servers inject full tool schemas into context on every turn whether the agent uses them or not. CLIs flip this: the agent runs a targeted command, and only the relevant output enters the context window. I use <code>agent-browser</code> heavily for exactly this reason versus using the Playwright MCP.</p><p><strong>Quick pause before we go further.</strong> Levels 3 through 5 are the building blocks for everything that follows. LLMs are unpredictably good at some things and bad at others, and you need to develop an intuition for where those edges are before stacking more automation on top. If your context is noisy, your prompts are under- or misspecified, or your tools are poorly described, levels 6 through 8 just amplify the mess.</p><p>This is where the rocket really starts to ship.</p><p>Context engineering is about curating what the model sees. <a href="https://openai.com/index/harness-engineering/" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Harness engineering</a> is about building the entire environment, tooling, and feedback loops that let agents do reliable work without you intervening. Give the agent the feedback loop, not just the editor.</p><div><figure class="my-6"><img alt="OpenAI's Codex harness — a full observability stack wired into the agent so it can query, correlate, and reason about its own output (source: OpenAI)" width="800" height="450" data-nimg="1" class="rounded-lg c1" sizes="(max-width: 768px) 100vw, 72ch" srcset="/_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=640&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 640w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=750&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 750w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=828&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 828w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=1080&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1080w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=1200&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1200w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=1920&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1920w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=2048&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 2048w, /_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 3840w" src="https://www.bassimeledath.com/_next/image?url=%2Fimages%2Fblog%2Fharness-eng.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT" /><figcaption class="mt-2 text-center text-sm text-muted">OpenAI's Codex harness — a full observability stack wired into the agent so it can query, correlate, and reason about its own output (source: OpenAI)</figcaption></figure></div><p>OpenAI's Codex team wired Chrome DevTools, observability tooling, and browser navigation into the agent runtime so it could take screenshots, drive UI paths, query logs, and validate its own fixes. Given a single prompt, the agent can reproduce a bug, record a video, and implement a fix. Then it validates by driving the app, opens a PR, responds to review feedback, and merges, escalating only when judgment is required. The agent doesn't just write code. It can see what the code produces and iterate on it, the same way a human would.</p><p>My team builds voice and chat agents for tech troubleshooting, so I built a CLI tool called <code>converse</code> that lets any LLM chat with our backend endpoint and have turn-by-turn conversations. The LLM makes code changes, uses <code>converse</code> to test conversations against the live system, and iterates. Sometimes these self-improvement loops run for several hours on end. This is especially powerful when the outcome is verifiable: the conversation must follow this flow, or call these tools in these situations (e.g., escalation to a human agent).</p><p>The concept that enables this is <a href="https://latentpatterns.com/glossary/agent-backpressure" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">backpressure</a>: automated feedback mechanisms (type systems, tests, linters, pre-commit hooks) that let agents detect and correct mistakes without human intervention. If you want autonomy, you need backpressure. Otherwise you end up with a slop machine. This extends to security too. <a href="https://vercel.com/blog/security-boundaries-in-agentic-architectures" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Vercel's CTO makes the case</a> that agents, the code they generate, and your secrets should live in separate trust domains, because a prompt injection buried in a log file can trick an agent into exfiltrating your credentials if everything shares one security context. Security boundaries are backpressure: they constrain what an agent <em>can</em> do when it goes off the rails, not just what it <em>should</em> do.</p><p>Two principles that sharpen this further:</p><ul><li><strong>Design for throughput, not perfection.</strong> When perfection is required per commit, agents pile on the same bug and overwrite each other's fixes. Better to tolerate small non-blocking errors and do a final quality pass before release. We do the same for our human colleagues.</li>
<li><strong>Constraints &gt; instructions.</strong> Step-by-step prompting ("do A, then B, then C") is increasingly outdated. In my experience, defining boundaries works better than giving checklists, because agents fixate on the list and ignore anything not on it. The better prompt is "here's what I want, work on it until you pass all these tests."</li>
</ul><p>The other half of harness engineering is making sure the agent can navigate your repo without you. OpenAI's approach: keep <code>AGENTS.md</code> to roughly 100 lines that serve as a table of contents pointing to structured docs elsewhere, and make documentation freshness part of CI rather than relying on ad hoc updates that go stale.</p><p>Once you've built all of this, a natural question emerges: if the agent can verify its own work, navigate the repo, and correct its mistakes without you, why do you need to be in the chair at all?</p><p>Heads up, for folks in the early levels, this next section may sound alien (but hey, bookmark and come back to it).</p><p>Hot take: plan mode is dying.</p><p>Boris Cherny, creator of Claude Code, still starts <a href="https://youtu.be/PQU9o_5rHC4?si=8j25qad3-J_DbCNX" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">80% of tasks</a> in plan mode today. But with each new model generation, the one-shot success rate after planning keeps climbing. I think we're approaching the point where plan mode as a separate human-in-the-loop step fades away. Not because planning doesn't matter, but because models are getting good enough to plan well on their own. Big caveat: this only works if you've done the work in levels 3 through 6. If your context is clean, your constraints are explicit, your tools are well-described, and your feedback loops are tight, the model can plan reliably without you reviewing it first. If you haven't done that work, you'll still need to babysit the plan.</p><p>To be clear, planning as a general practice isn't going away. It's just changing shape. For newer practitioners, plan mode remains the right entry point (as described in Levels 1 and 2). But for complex features at Level 7, "planning" looks less like writing a step-by-step outline and more like exploration: probing the codebase, prototyping options in worktrees, mapping the solution space. And increasingly, background agents are doing that exploration for you.</p><p>This matters because it's exactly what unlocks background agents. If an agent can generate a solid plan and execute without needing you to sign off, it can run asynchronously while you do something else. That's the critical shift from "multiple tabs I'm juggling" to "work that's happening without me."</p><p>The <a href="https://ghuntley.com/loop/" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Ralph loop</a> is the popular entry point: an autonomous agent loop that runs a coding CLI repeatedly until all PRD items are complete, where each iteration spawns a fresh instance with clean context. In my experience, getting the Ralph loop right is hard and any under/misspecification of the PRD comes back to bite. It's a little too fire-and-forget.</p><p>You can run multiple Ralph loops in parallel, but the more agents you spin up, the more you notice where your time actually goes: coordinating them, sequencing work, checking output, nudging things along. You're not writing code anymore. You've become a middle manager. You need an orchestrator agent that handles the dispatch so you can stay focused on intent, not logistics.</p><div><figure class="my-6"><img alt="Dispatch launching 5 workers across 3 models in parallel — your session stays lean while agents do the work" width="800" height="450" data-nimg="1" class="rounded-lg c1" sizes="(max-width: 768px) 100vw, 72ch" srcset="/_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=640&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 640w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=750&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 750w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=828&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 828w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=1080&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1080w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=1200&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1200w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=1920&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 1920w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=2048&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 2048w, /_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT 3840w" src="https://www.bassimeledath.com/_next/image?url=%2Fimages%2Fblog%2Fdispatch.png&amp;w=3840&amp;q=75&amp;dpl=dpl_8x7zvri6T9MRoxumkhuHo38urKcT" /><figcaption class="mt-2 text-center text-sm text-muted">Dispatch launching 5 workers across 3 models in parallel — your session stays lean while agents do the work</figcaption></figure></div><p>The tool I've been using heavily for this is <a href="https://github.com/bassimeledath/dispatch" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Dispatch</a>, a <a href="https://www.bassimeledath.com/blog/dispatch" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Claude Code skill I built</a> that turns your session into a command center. You stay in one clean session while workers do the heavy lifting in isolated contexts. The dispatcher plans, delegates, and tracks, so your main context window is preserved for orchestration. When a worker gets stuck, it surfaces a clarifying question rather than silently failing.</p><p>Dispatch runs locally, which makes it ideal for rapid development where you want to stay close to the work: faster feedback, easier to debug interactively, and no infrastructure overhead. <a href="https://builders.ramp.com/post/why-we-built-our-background-agent" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Ramp's Inspect</a> is the complementary approach for longer-running, more autonomous work: each agent session spins up in a cloud-hosted sandboxed VM with the full development environment. A PM spots a UI bug, flags it in Slack, and Inspect picks it up and runs with it while your laptop is closed. The tradeoff is operational complexity (infrastructure, snapshotting, security), but you get scale and reproducibility that local agents can't match. I'd say use both (local and cloud background agents).</p><p>One pattern that's been surprisingly powerful at this level: use different models for different jobs. The best engineering teams aren't staffed with clones. They're staffed with people who think differently, trained by different experiences, bringing different strengths. The same logic applies to LLMs. These models were post-trained differently and have meaningfully different dispositions. I routinely dispatch Opus for implementation, Gemini for exploratory research, and Codex for review, and the cumulative output is stronger than any single model working alone. Think wisdom of crowds, but for code.</p><p>Critically, you also need to decouple the implementer from the reviewer. I've learned this the hard way too many times: if the same model instance implements and evaluates its own work, it's biased. It will gloss over issues and tell you all tasks are complete when they aren't. It's not malice, it's the same reason you don't grade your own exam. Have a different model (or a different instance with a review-specific prompt) do the review pass. Your signal quality goes way up.</p><p>Background agents also open the floodgates for combining your CI with AI. Once agents can run without a human in the chair, trigger them from your existing infrastructure. A docs bot that regenerates documentation on every merge and raises a PR to update <code>CLAUDE.md</code> (we do this and it's a huge time saver). A security reviewer that scans PRs and opens fixes. A dependency bot that actually upgrades packages and runs the test suite rather than just flagging them. Good context, compounding rules, capable tools, and automated feedback loops, now running autonomously.</p><p>Nobody has mastered this level yet, though a few are pushing into it. It's the active frontier.</p><p>In Level 7, you have an orchestrator LLM dispatching work to worker LLMs in a hub-and-spoke pattern. Level 8 removes that bottleneck. Agents coordinate with each other directly, claiming tasks, sharing findings, flagging dependencies, and resolving conflicts without routing everything through a single orchestrator.</p><p>Claude Code's experimental <a href="https://code.claude.com/docs/en/agent-teams" class="text-foreground underline decoration-[rgb(var(--link-underline))] underline-offset-[3px] transition-[text-decoration-color] duration-200 hover:decoration-accent" target="_blank" rel="noopener noreferrer">Agent Teams</a> feature is an early implementation: multiple instances work in parallel on a shared codebase, where teammates operate in their own context windows and communicate directly with each other. Anthropic used 16 parallel agents to build a C compiler from scratch that can compile Linux. Cursor ran hundreds of concurrent agents for weeks to build a web browser from scratch and migrate their own codebase from Solid to React.</p><p>But look closely and you'll see the seams. Cursor found that without hierarchy, agents became risk-averse and churned without progress. Anthropic's agents kept breaking existing functionality until a CI pipeline was added to prevent regressions. Everyone experimenting at this level says the same thing: multi-agent coordination is a hard problem and nobody is near optimal yet.</p><p>I honestly don't think the models are ready for this level of autonomy for most tasks. And even if they were smart enough, they're still too slow and too token-hungry for it to be economical outside of moonshot projects like compilers and browser builds (impressive, but far from clean). For the work most of us do day to day, Level 7 is where the leverage is. I wouldn't be surprised if Level 8 becomes the prevailing pattern eventually, but right now Level 7 is where I'd put my energy (unless you're Cursor and the breakthrough <em>is</em> the business).</p><p>Inevitable what's next question.</p><p>Once you're adept at orchestrating agent teams without much friction, there's no reason the interface has to stay text-only. Voice-to-voice (thought-to-thought, maybe?) interaction with your coding agent — conversational Claude Code, not just voice-to-text input — is a natural next step. Look at your app, describe a sequence of changes out loud, and watch them happen in front of you.</p><p>There's a crowd chasing the perfect one-shot: state what you want and the AI composes it flawlessly in a single pass. The problem is that this presupposes we humans know exactly what we want. We don't. We never have. Software has always been iterative, and I think it always will be. It's just going to get much easier, stretch well beyond plain text interactions, and be a heck of a lot faster.</p><p>So: what level are you on? And what are you doing to get to the next one?</p><div class="not-prose my-10 rounded-lg border border-border p-6 sm:p-8"><div class="flex items-center justify-between"><p class="text-xs font-medium uppercase tracking-wider text-muted">What level are you?</p><p class="text-xs text-muted">1 / 7</p></div><p class="mt-4 font-serif text-lg font-medium leading-snug text-foreground sm:text-xl">How do you typically start a coding task with AI?</p></div>]]></description>
      <link>https://www.bassimeledath.com/blog/levels-of-agentic-engineering</link>
      <guid>https://www.bassimeledath.com/blog/levels-of-agentic-engineering</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Whistleblower claims ex-DOGE member says he took Social Security data to new job]]></title>
      <description><![CDATA[The Social Security inspector general’s office is investigating allegations that the former DOGE engineer took sensitive data on a thumb drive in a major potential security breach, said people familiar with the process.]]></description>
      <link>https://www.washingtonpost.com/politics/2026/03/10/social-security-data-breach-doge/</link>
      <guid>https://www.washingtonpost.com/politics/2026/03/10/social-security-data-breach-doge/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Claude | Claude Help Center]]></title>
      <description><![CDATA[]]></description>
      <link>https://support.claude.com/en/collections/4078531-claude</link>
      <guid>https://support.claude.com/en/collections/4078531-claude</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[OpenClaw fever: why is China rushing to ‘raise a lobster’? | South China Morning Post]]></title>
      <description><![CDATA[<p>As global concern rises over artificial intelligence and the potential for AI agents to disrupt lives and industries, people in southern China are rushing to embrace the technology even as privacy concerns intensify.
On Friday, nearly 1,000 people lined up outside Chinese tech giant Tencent Holdings’ Shenzhen headquarters to install OpenClaw – a popular open-source AI agent software – on their computers.
The crowd, a mix of amateur developers, retired space engineers, housewives, students and AI enthusiasts, gathered following an invitation from Tencent’s cloud-computing unit, with the company’s engineers installing the software for free.
Meanwhile, social media was awash with posts offering the same service for fees ranging from tens to hundreds of yuan.
Tencent’s initiative reflects the latest effort from a Chinese tech company to capitalise on surging enthusiasm for OpenClaw, which has spilled beyond the developer community to hobbyists and ordinary users.

Mark Yang, a Shanghai-based designer and early OpenClaw adopter, said with the AI assistant it felt like having “virtual staff” that handled assignments and reduced workload.
OpenClaw, formerly known as Clawdbot and Moltbot, was developed by Austrian programmer Peter Steinberger and released last year to global fanfare. Last month, Microsoft-backed US frontier AI lab OpenAI acquired the open-source autonomous AI agent.
Unlike conventional chatbots that mostly interact with users, OpenClaw – billed as the AI that actually does things – was designed to carry out tasks on users’ computer systems on their behalf. That vision helped it take the world by storm, offering a glimpse of a future where everyone has their own Jarvis, the omniscient AI assistant from Marvel Comics’ Iron Man movie franchise.
Adopting OpenClaw has been dubbed “raise the lobster” by Chinese consumers, who are flocking to use it for everything from stock picking and report writing to slide decks, emails and coding.
The adoption rush comes despite concerns, as OpenClaw typically requires high-level control of a user’s computer system to function, making it a potential privacy risk.
Speaking at a Morgan Stanley Technology, Media &amp;amp; Telecom conference in San Francisco on Wednesday, Nvidia CEO Jensen Huang said that “OpenClaw is the single most important release of software probably ever”.
Despite the hype, installing OpenClaw and getting it to run properly was proving challenging for users without advanced technical knowledge, according to Beijing-based software developer Hu Zhicheng. He added that the barrier explained why paid installation services were popular on local social media platforms.
Apart from installing OpenClaw, a social media post from Tencent’s cloud unit on Friday said engineers would help set up AI models, connect with third-party services and enable various skills.
Many online sessions and offline events have also sprung up across mainland China, from Beijing and Shenzhen to Hangzhou, to share know-how and encourage adoption of OpenClaw.


Afra Wang, a writer who covers Chinese tech and is the author of the Substack newsletter Concurrent, went to one such event last month, where she saw first-hand a tremendous interest in OpenClaw among the country’s independent developer community.
“Two weeks ago a friend organised an OpenClaw meet-up [in Hangzhou], where so many people showed up that they had to restrict attendance,” Wang said in a post on X on Thursday. “Now he’s hosting another talk in Shenzhen and 900+ people have registered.”
Other major Chinese tech companies would now be eyeing the trend, eager to join the bandwagon, after OpenClaw-style AI agents were featured in the government’s annual work report for the first time.
“We will promote faster application of new-generation intelligent terminals and AI agents, and encourage large-scale commercial application of AI in key sectors and fields, so as to foster new forms and models of AI-native business,” according to the work report delivered by Premier Li Qiang at the opening of China’s top legislative meeting, the National People’s Congress, in Beijing on Thursday.
Last week, smartphone vendors Xiaomi and ZTE-backed Nubia announced the integration of OpenClaw-like capabilities in some of their models.
Cloud services providers from ByteDance to Alibaba Group Holding were also offering solutions to have OpenClaw installed on their cloud platforms, aiming to alleviate privacy concerns. Alibaba owns the South China Morning Post.
Among those swept up in the excitement to ‘raise a lobster’ is Fu Sheng. The veteran Chinese tech entrepreneur developed an OpenClaw-based agent named Sanwan while recovering from a skiing accident during the Chinese New Year holiday.
Fu spent 14 days developing Sanwan into a reliable 24X7 personal assistant. The AI agent helped him send Chinese New Year greetings to more than 600 friends in four minutes, write and publish social media posts that garnered more than 1 million views while he slept, and handle a range of other tasks.
Fu documented the entire process on the website sanwan.ai, which was designed, coded and launched by Sanwan.
“When I work with human staff, no one acts immediately [on requests], but [Sanwan] is different, there’s no need to schedule or wait,” Fu said. “Changes come immediately at your command.”</p>]]></description>
      <link>https://www.scmp.com/tech/tech-trends/article/3345865/openclaw-fever-why-china-rushing-raise-lobster</link>
      <guid>https://www.scmp.com/tech/tech-trends/article/3345865/openclaw-fever-why-china-rushing-raise-lobster</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[I don’t know what is Apple’s endgame for the Fn/Globe key, and I’m not sure Apple knows either – Aresluna]]></title>
      <description><![CDATA[<header><p>Marcin Wichary</p>
<p>9 March 2026 / 4,000 words / 55 images</p>
</header><p>Every modifier key starts simple and humble, with a specific task and a nice matching name.</p><p>This never lasts. The tasks become larger and more convoluted, and the labels grow obsolete. Shift no longer shifts a carriage, Control doesn’t send control codes, Alt isn’t for alternate nerdy terminal functions.</p><p>Fn is the newest popular modifier key, and it feels we’re speedrunning it through all the challenges without having learned any of the lessons.</p><hr /><h3 class="number">1</h3><p>The first Fn key that mattered arrived with perhaps the most cursed and ridiculed computer in history, IBM’s 1984 PCjr.</p><figure class="width-chute-narrow aspect-portrait-34 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/pcjr-computer.avif" alt="image" /></figure><p>PCjr was envisioned as a home version of the massively popular office 1981 PC and its revered Model F keyboard:</p><figure class="width-bleed aspect-landscape-169"><img src="https://aresluna.org/fn/images/fn/pc-keyboard.avif" alt="image" /></figure><figcaption>IBM PC keyboard (1981) Courtesy Eric Keppel</figcaption><p>Depending on how you look at it, PCjr’s keyboard was cut to hell for reasons of either cost or simplicity. Its key count – 21 fewer than the PC – was similar to the Macintosh’s keyboard that debuted just two months earlier. But the Mac was starting anew, and IBM had to deal with the baggage of the 3-year-old platform. The promise of software compatibility of the new home computer with its “senior” predecessor came with a design challenge: keys couldn’t simply be removed.</p><p>The solution was the Fn key, put in the upper right corner, meant to bring back from the dead the missing keys by making the surviving ones pretend to be them:</p><p>Just like the first-ever Shift key was, some century earlier.</p><figure class="width-bleed aspect-landscape-169"><img src="https://aresluna.org/fn/images/fn/pcjr-keyboard.avif" alt="image" /></figure><figcaption>IBM PCjr keyboard (1984)</figcaption><p>The system was color-coded in a neat way that was easy to understand. FnP would do the same as PrtSc on the larger keyboard, Fn6 would simulate F6, and so on.</p><p>The label “Fn,” in hindsight, was a bit unfortunate. There was some sense to it, as the key was changing the <em>function</em> of other keys. But there already were 10 function keys on other keyboards. Adding another thing that could be called a “function key” into the mix was tricky.</p><p>Most importantly for our conversation, the Fn key was resolved <em>internally</em> inside the keyboard. When you pressed FnS, the keyboard would not report those two keys to the host computer. Instead, it would only send an event for the ghost key it represented, Scroll Lock. To the computer, it really seemed like the missing key was there.</p><div class="figure-group width-chute mobile-bleed mobile-streamline"><figure class="aspect-landscape-43"><img src="https://aresluna.org/fn/images/fn/pcjr-manual/1.avif" alt="image" /></figure><figure class="aspect-landscape-43"><img src="https://aresluna.org/fn/images/fn/pcjr-manual/2.avif" alt="image" /></figure></div><figcaption>Excerpts from the IBM PCjr manual</figcaption><p>Like many computers at that time, PCjr also had a bunch of “computer operation” shortcuts – the kind of things you might expect on the fascia of the computer case itself. The most famous one, CtrlAltDel, requires no explanation. The others – CtrlAlt← or → for adjusting the position of the screen, and CtrlAltCaps Lock to toggle keyboard clicking – were molded in the original’s image.</p><hr /><h3 class="number">2</h3><p>The creators of PCjr chose to make their keyboard small and cuddly. The laptop companies didn’t have a choice: the machines had to be small, and some of the keys simply couldn’t fit.</p><p>PCjr <a target="_blank" href="https://en.wikipedia.org/wiki/IBM_PCjr#Release_and_reception">crashed and burned</a>, and was followed two years later by PC Convertible, the machine Cathode Ray Dude once named <a target="_blank" href="https://www.youtube.com/watch?v=htl_JbZIcUU">the longest laptop ever made</a>. But the Fn convention stuck; even though the laptop actually came with 10 proper function keys atop, a few other missing keys still needed representation.</p><figure class="width-bleed aspect-square"><img src="https://aresluna.org/fn/images/fn/pc-convertible-2.avif" alt="image" /></figure><p>A year later, in 1987, Toshiba’s early T1000 and T1200 laptops did something similar. Eventually, so did Zenith, Tandy, Samsung, and pretty much every laptop and then notebook manufacturer.</p><div class="width-chute figure-group mobile-streamline mobile-bleed"><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/compaq.avif" alt="image" /></figure><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/thinkpad-butterfly.avif" alt="image" /></figure></div><div class="width-chute figure-group mobile-streamline mobile-bleed"><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/psion.avif" alt="image" /></figure><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/zenith.avif" alt="image" /></figure></div><figcaption>Machines from Compaq, IBM, Psion, and Zenith / In Poland, a border around a name on a movie poster means the person died during the production of the movie, so it’s hard for me not to see this Fn convention as honoring the fallen comrades.</figcaption><p>Just like in 1984, Fn was used to make keys pretend they’re Home, End, PgUp, PgDn, plus a few more rare keys like Break or PrtSc. But nature abhors a vacuum, freeways generate traffic, and keys end up being given more work.</p><p>Fn’s tasks were quickly expanded to simulate the numeric keypad, or the newer and oft-omitted F11 and F12 keys. Then, designers realized that the “computer operation” shortcuts could benefit from being assigned to Fn rather than the more cumbersome CtrlAlt prefix. And so, PC Convertible allowed FnCaps Lock to toggle keyboard clicking, on Toshiba’s laptops Fn→ would swap fonts on the screen, and on Packard Bell’s FnF7 inverted the colors.</p><p>The battle between CtrlAlt and Fn raged on for a few years. NEC Ultralite in 1988 had a small red Fn key wedged between Ctrl and Alt, but still used CtrlAltH for high and L for low speed – the keyboard equivalent of the <a target="_blank" href="https://en.wikipedia.org/wiki/Turbo_button">Turbo button</a> on the desktop case. Other laptops, however, already used Fn for this purpose: Fn+ and –, FnF3 and F4, or FnPgUp and PgDn.</p><figure class="width-chute-narrow aspect-landscape-41 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/external-fn-manual.avif" alt="image" /></figure><figcaption>A rare thoughtful gesture allowing to use Fn on an external keyboard that might not have it. In screenwriting school, I believe what I’m doing is called “foreshadowing.”</figcaption><p>Standardization was indeed rare. Swapping to an external display was FnEnd on a Toshiba, FnPrtSc on an HP, and FnF5 on… a different HP model. HP also allowed FnSpace to mute the system, while on European versions of Tandy 1000FD, the same combination acted as the missing backslash and pipe key.</p><p>But a common meta convention started appearing at least, and it was a sort of perversion of the original idea established by the PCjr. Notebooks all came with a row of F1–F10 function keys, and many of those keys started to have internal second lives devoted to computer operation. Volume control, screen brightness control, and over time things like connecting to external display, battery status, and so on were all assigned to some combination of Fn plus a function key, with legends in distinctive color on fronts of keys back when the keys had fronts.</p><div class="figure-group width-chute-narrow mobile-bleed"><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/powerbook-sliders.avif" alt="image" /></figure><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/omnibook-brightness.avif" alt="image" /></figure></div><figcaption>Physical brightness and contrast sliders on the PowerBook 165C from 1993, and Fn combinations from HP OmniBook 3000 from 1997 Photo courtesy Adam Richardson</figcaption><p>The Fn key itself was typically somewhere in the lower-left corner of the keyboard. And while pretty much every computer did specific combinations slightly differently, the standard purpose for Fn emerged to be these two jobs:</p><ul><li>help resurrect keys known from larger, over-100-key keyboards</li>
<li>operate internal functions of the computer, usually assigned to the function key row</li>
</ul><figcaption>Excerpts from manuals explaining Fn keys: IBM PCjr, HP OmniBook 800, HP OmniBook 3000.</figcaption><p>Eventually, we went full circle, and some desktop keyboards embraced Fn again for reasons of space constraints, desires for power-user customization, or both.</p><div class="figure-group width-chute mobile-bleed mobile-streamline"><figure class="aspect-landscape-43"><img src="https://aresluna.org/fn/images/fn/third-party/triangular.avif" alt="image" /></figure><figure class="aspect-landscape-43"><img src="https://aresluna.org/fn/images/fn/third-party/microtron.avif" alt="image" /></figure></div><div class="figure-group width-chute mobile-bleed mobile-streamline"><figure class="aspect-landscape-43"><img src="https://aresluna.org/fn/images/fn/third-party/hhkb.avif" alt="image" /></figure><figure class="aspect-landscape-43"><img src="https://aresluna.org/fn/images/fn/third-party/keyboardio.avif" alt="image" /></figure></div><figcaption>Microtron, HHKB, and Keyboardio Model 100</figcaption><hr /><h3 class="number">3</h3><p>This brings us neatly to the era of Windows.</p><p>Fn was far from the first modifier, of course, and this is where PCs started with a lot of historical baggage. Shift came from typewriters, Control from teletypes, Alt from earlier IBM mainframes, and even Backspace from the times where that early typewriter key was simply… a space going back without any deletion.</p><figcaption>Modifier keys in their original habitat</figcaption><p>After witnessing the DOS apps becoming a wild west of keyboard shortcuts and conventions, Microsoft ventured to standardize stuff with Windows, and did a pretty good job. Control was now for shortcuts like copy and paste, and Alt for <a target="_blank" href="https://unsung.aresluna.org/a-tiny-bit-old-windows-got-right/">alternate visual keyboard access</a>. (There was also the unfortunately named AltGr, for printing accent letters needed in Europe.)</p><p>And then, around mid-1990s, Microsoft performed something of a power grab. The company invented a new modifier key, Windows (⊞), and basically told all the computer manufacturers: Hey, do you want all the Chicago attention? Then you better put a new key with a Windows logo on your keyboard.</p><p>Chicago became the ultrafamous Windows 95, and just around the same time, Microsoft itself also started producing the popular Natural Keyboard with the new keys.</p><div class="figure-group width-chute mobile-bleed mobile-streamline"><figure class="aspect-landscape-169"><img src="https://aresluna.org/fn/images/fn/natural-prototype.avif" alt="image" /></figure><figure class="aspect-landscape-169"><img src="https://aresluna.org/fn/images/fn/natural-final.avif" alt="image" /></figure></div><figcaption>In the prototypes of Natural Keyboard, the ⊞ key was in the lower left corner, but the production model moved it between Ctrl and Alt keys. This placement challenge is an ongoing tension for Windows users for whom Ctrl is the main shortcut modifier key.</figcaption><p>The difference between the Windows key and the modifiers that came before was that ⊞ was reserved for the operating system. A single press popped up the heavily advertised Start menu, and other combinations were there for system-wide stuff, including a lot of windowing: ⊞D to show the desktop, ⊞R to run a command, ⊞M for minimizing all windows, and so on. No apps could claim a shortcut starting with ⊞.</p><hr /><p>Apple’s path ended up going in the opposite direction. The beginnings with the 1983’s Lisa and the 1984’s Mac were great in their simplicity: Shift was too well-known to mess with, but the other two keys were called Command (for invoking commands) and Option (for alternate keys and as an eventual condiment for more complicated shortcuts). The keys came with iconography – ⇧ and ⌘ and ⌥ – that allowed their presence in menus and eventually tooltips to be compact, which meant you could announce them more easily on cramped screens of yesteryear. Some of the shortcuts, particularly ⌘Z for undo and ⌘XCV for cut/copy/paste, became iconic and used world over.</p><p>Backspace was also renamed to a better Delete, but PC already used Delete for what Apple termed Forward Delete. Neither company suspected their decisions will get intertwined for decades to come, causing extra confusion.</p><p>But what followed was a series of blunders.</p><p>The 1986 keyboard, compatible with both Apple IIgs and the Mac, put the Apple logo on the same key as “⌘”. This was meant to help users from each platform, but the end result was catastrophic: since the ⌘ symbol didn’t have an intuitive generic name (propeller? cloverleaf? splat?), now <em>Mac users</em> started thinking of the command key as “the Apple key.”</p><figure class="width-chute-narrow aspect-landscape-21 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/apple-desktop-bus.avif" alt="image" /></figure><figcaption>Apple Desktop Bus keyboard</figcaption><p>Then there was 1987, when now Mac succumbed to the curse of the fourth year. A platform in trouble after a few years of moribund sales chose to court expandability and PC compatibility, and the new batch of keyboards of that era added previously unimaginable PC affordances. There were now F1–F15 function keys and Num Lock and Scroll Lock lights. A bunch of alternate labels were added, too: F13 was adorned with “Print Screen,” Option got twin-labeled with “Alt,” and Forward Delete received an extra “Del” legend, even though it was right next to a key already labeled Delete.</p><figure class="width-chute-narrow aspect-landscape-21 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/apple-extended.avif" alt="image" /></figure><figcaption>The layout of the Apple Extended Keyboard also resembled IBM’s Model M</figcaption><p>Most crucially, both keyboards introduced a new tenant: Control (⌃). This was modifier key number four, and to this day, I don’t fully understand why ⌘ wasn’t repurposed here, and Apple just slapped on another modifier key with a very similar purpose.</p><p>The end result of these decisions was two decades of confusion. Only in 2007, the Apple II computer platform long gone, the company removed their famous logo from Mac’s keys. (The secondary “Alt” label started disappearing 28 years after it was introduced, in 2015, and at the same time Apple began doing something they should have been all along: they consistently started putting text labels next to mysterious symbols on all their keyboard variants.)</p><div class="figure-group width-chute-narrow mobile-bleed"><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/apple-2000s/2.avif" alt="image" /></figure><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/apple-2000s/3.avif" alt="image" /></figure></div><div class="figure-group width-chute-narrow mobile-bleed"><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/apple-2000s/8.avif" alt="image" /></figure><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/apple-2000s/7.avif" alt="image" /></figure></div><figcaption>Apple keyboards from 2003, 2003, 2009, and 2017. Note how on some of the keyboards, the bottom-row keys are lightly taller than the other rows.</figcaption><p>But another kind of damage was even harder to undo. In 1995, Apple ostensibly had the same number of modifier keys as Microsoft – ⌘⌥⌃ vs. CtrlAlt⊞ – but at least on the PC side, the ⊞ key was scoped neatly to a very specific set of tasks under precise control of the operating system. On Macs, the modifier keys were unbound and effectively interchangeable, so despite Apple’s protestations…</p><blockquote><div>The Control key is used with terminal-emulation programs for control-key sequences. For all other applications, it is reserved for end-user-defined shortcut key sequences using a macro-key facility.</div></blockquote><p>…more advanced keyboard shortcuts in various apps started reaching for either ⇧ or ⌥ or ⌃ – first in addition to ⌘, and eventually solo – because all were available.</p><p>And, as both operating systems started appearing on notebooks, they welcomed to the bottom row the already well-established Fn key. On the Mac, the key first appeared with the 1997 PowerBook G3 – color-coordinated as other laptops have been doing, and offering similar functionality.</p><p>Although the Mac, always uneasy with F1–F12 function keys, reversed the meaning of Fn from day one. You had to hold Fn by default to get to function keys, although you could switch that behavior permanently in software.</p><figure class="width-chute-narrow aspect-square mobile-bleed"><img src="https://aresluna.org/fn/images/fn/pismo.avif" alt="image" /></figure><figcaption>PowerBook G3 Pismo Raimond Spekking/CC BY-SA 4.0</figcaption><p>Over the next decade, as the internet explosion caused computers to reach more and more casual consumers, the internal numeric keypad emulation disappeared, and in 2007 Apple’s smaller notebook-like keyboard became available for desktop computers as well.</p><div class="figure-group width-chute mobile-bleed mobile-streamline"><figure class="aspect-landscape-41"><img src="https://aresluna.org/fn/images/fn/press-fn-convertible.avif" alt="image" /></figure><figure class="aspect-landscape-41"><img src="https://aresluna.org/fn/images/fn/press-fn-powerbook.avif" alt="image" /></figure></div><figcaption>Even at that time, the specifics of Fn could be confusing. These are excerpts from manuals of the 1986 PC Convertible and a 1997 PowerBook, giving conflicting advice.</figcaption><hr /><h3 class="number">4</h3><p>And then things got <em>really</em> messy for the poor Fn key.</p><p>In 2012, with the release of Mac OS Mountain Lion, Apple crossed a line no edition of the key attempted before: one of the <a target="_blank" href="https://web.archive.org/web/20120815051948/http://www.apple.com/osx/whats-new/features.html#dictation">signature releases of the operating system</a> allowed you to tap Fn twice to enable dictation.</p><figure class="width-chute-narrow image-transparent mobile-bleed"><img data-width="1674" data-height="1242" src="https://aresluna.org/fn/images/fn/dictation-mountain-lion.avif" alt="image" /></figure><figcaption>Screenshot from <a target="_blank" href="https://512pixels.net/projects/aqua-screenshot-library/">macOS Screenshot Library at 512 Pixels</a>.</figcaption><p>From user’s standpoint, it was a nice and convenient gesture. But for the first time, this was Fn key doing a regular key’s work. Previously, Fn’s tasks were either related to computer hardware and something the operating system never knew about (screen brightness, volume, and so on), or otherwise the signals sent to the computer were of the other keys Fn was resurrecting (e.g. pressing FnDelete sent over Forward Delete). But here, there was no dictation key to simulate. The Fn key itself had a personality it had to announce to the operating system.</p><figure class="width-super-aside aspect-square"><img src="https://aresluna.org/fn/images/fn/menu-fn-fn.avif" alt="image" /></figure><p>This worked within the closed proprietary confines of Apple’s keyboards built-in and external. But it immediately complicated things for third-party keyboards. They either didn’t have the Fn key – or if they did, Fn was never supposed to work and be visible in that way.</p><p>It was that moment in 2012 when you start seeing a trickle of users complaining online about Fn being confusing. (Spoiler: the complaints continue until today.) Sure, Apple provided alt options for dictation, including other shortcuts and onscreen buttons to tap. But you had to know you can switch the shortcut, and then do it yourself. If you didn’t, for the first time you might have spotted in the menu a key that you didn’t have. Worse, if you did, it might not have – it <em>could</em> not have – worked!</p><p>The second domino was iPad Pro’s release in 2015. Prior official iPad keyboards didn’t have an Fn key, but the magnetic Smart Keyboard arrived with a key in the lower left corner with a completely new symbol: . The globe key allowed to switch between keyboard layouts, one of which included a useful emoji keyboard during the peak of emoji’s cultural relevance.</p><p>New in the context of hardware keyboards. The globe key existed on iPhone’s onscreen keyboard ever since November 2007.</p><figure class="width-chute aspect-landscape-21 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/ipad-pro-2015.avif" alt="image" /></figure><p>Reviewers were <a target="_blank" href="https://brooksreview.net/2015/11/smart-keyboard/">perplexed</a> by the lack of other iOS-specific keys – even previous iPad keyboards from Apple had a home key – but over time they discovered that “traditional” shortcuts like ⌘H and ⌘Tab worked for that purpose.</p><figure class="width-super-aside aspect-portrait-34"><img src="https://aresluna.org/fn/images/fn/kotoeri.avif" alt="image" /></figure><figcaption>Curiously, Apple’s Japanese keyboards up until the early 2000s used Ctrl for language selection, even adorning it with a printed pencil symbol announcing that feature.</figcaption><p>At that point, it seemed Apple wanted to basically bring Mac-style shortcuts to the iPad, and somehow deemed the layout swapping important enough to promote to a newfangled corner key. In 2019 and 2020, the Globe key crossed over: the new MacBooks started adding the globe icon alongside the existing “Fn” label and allowing to access keyboard layouts the same way.</p><p>But it was 2021 where an enormous new piece of a puzzle dropped. It turned out that this was a different story. Twenty-seven years since Microsoft did so, Apple too wanted a Windows-style key that only they could control.</p><p>Suddenly, the globe key on the iPad and the hybrid globe/Fn key on the Mac were equipped with a million Windows-like tasks: C to activate Control Center, A to show the dock, N for Notification Center, and so on. There was also ← and → to jump between apps (even though ⌘Tab also did that), H to go to the home screen (same as ⌘H), F for fullscreen (also available via ⌃⌘F), and a bunch of other window management functions. You could even press D for dictation, even though by now F5 was promoted to serve the same purpose.</p><figure class="width-chute aspect-landscape-169 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/wwdc-2021.avif" alt="image" /></figure><figcaption>A scene from the WWDC 2021 keynote and the first appearance of -based shortcuts</figcaption><p>But Apple kept their new /Fn key close to their chest – only Apple keyboards and selected partners were allowed to generate the right code. This resulted in a complex scenario where Logitech keyboards for the iPad had a functioning  key, but other Logitech keyboards came with this warning:</p><blockquote><div>The Fn key on Logitech keyboards, when connected to macOS or iOS, functions differently from the Fn/Globe key on Apple. […] Logitech keyboards do not send the Fn/Globe key keycode in a manner that is compatible with Apple's specific shortcuts. As a result, certain Apple functions, such as window tiling and other shortcuts reliant on the Fn/Globe key, are not supported by our keyboards.</div></blockquote><p>It wasn’t just people complaining – now it seemed even Apple’s partners were.</p><p>In 2012, the problem of a key combination that didn’t sometimes exist or didn’t sometimes work was limited to dictation. In 2021, Apple extended the blast radius, and since added even more  shortcuts for window management – but ignored all of the original problems.</p><hr /><h3 class="number">5</h3><p>What is Apple’s way out of this? I have no idea.</p><p>What is there right now is not sustainable. I use a third-party keyboard and I’m seeing shortcuts in menu items that I simply <em>cannot press</em>:</p><figure class="width-chute-narrow aspect-square mobile-bleed"><img src="https://aresluna.org/fn/images/fn/menu-screenshots.avif" alt="image" /></figure><p>Sometimes they use the “” symbol, sometimes they say “fn” – but the latter doesn’t work for external keyboards where Fn still means something it meant since 1984.</p><figcaption>Three apps on my computer, and three different and confusing ways to acknowledge Full Screen has two shortcuts: ⌃⌘F and F</figcaption><p>Another option is Apple managing to convince keyboard manufacturers to add a  key everywhere, and treat it as a new modifier key. But even then, I imagine many keyboard manufactures will still want a traditional Fn key they can fully control. After all, many keyboards are their own computers now; my mechanical keyboard dedicates a lot of Fn shortcuts to internal actions like switching layers, controlling backlight, and Bluetooth connectivity. Others do <a target="_blank" href="https://www.reddit.com/r/Keychron/comments/lrr970/list_of_shortcuts_in_keychron_keyboards">a lot more</a>. There are also entirely too many layouts with too many missing keys to assume Apple’s mappings will work for everyone in perpetuity: What if Apple at some point decides that Esc means something, and you already used it for something else?</p><p>Many gaming keyboards have a “game mode” that disables the ⊞ modifier key which, pressed alone and by accident, ejects people from the game onto Windows desktop. Deliciously, in some keyboards, game mode is activated by… holding Fn+⊞.</p><p>So what are all these keyboards supposed to do – have both Fn and , effectively adding a <em>sixth</em> modifier key?</p><p>If Apple was the sole manufacturer of all keyboards, this would maybe make sense – but obviously so many other keyboards exist, and people want them for reasons of aesthetics, efficiency, and accessibility. And if this is meant as a <em>benefit</em> of using Apple keyboards, then it feels extremely misguided.</p><p>Look at any system shortcut list in macOS, and you realize it’s filled with strange inconsistencies – why can you map  solo to reveal the desktop, but cannot map Mission Control to ↑ – only to Ctrl↑?</p><figure class="width-chute-narrow image-transparent aspect-landscape-43 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/tahoe-mission-control.avif" alt="image" /></figure><figcaption>This is a confusing set of shortcuts as a whole. To Apple’s credit, I found no new functionality put under  that cannot be remapped – however awkwardly – to another combination, at least on a Mac.</figcaption><p>On a Mac, in particular,  doesn’t make sense since tons of existing ⌘ shortcuts are “global” anyway: ⌘H to hide a window, ⌘Space to search, ⌘Tab to jump between apps. I can’t imagine Apple moving them to a Globe combination, because  is unpleasant to press: small, far away from your thumb, and only available on the left side.</p><p>Why weren’t, for example, the <a target="_blank" href="https://unsung.aresluna.org/how-to-shoot-a-screen-using-a-board-of-keys/">extremely awkward screenshot-taking shortcuts</a> globed already? Probably, I imagine, because they wouldn’t be available at all to many people; right now, Apple can only add  shortcuts that didn’t exist before and didn’t lodge themselves in motor memories of their users. But how many more new shortcuts do we need? And what’s the plan for the existing ones?</p><p>On top of it all, Apple already failed at making the new key combinations work the same between the two platforms it introduced it to:  plus arrow keys means something else on the iPad and something else on a Mac.</p><p>I continue seeing <a target="_blank" href="https://www.reddit.com/r/RoyalKludge/comments/y33gd7/dear_mac_users_where_can_i_find_the_globe_key_on/">c</a><a target="_blank" href="https://discussions.apple.com/thread/256163709">o</a><a target="_blank" href="https://discussions.apple.com/thread/7408870?sortBy=rank">n</a><a target="_blank" href="https://discussions.apple.com/thread/252165525?sortBy=rank">f</a><a target="_blank" href="https://forum.keyboardmaestro.com/t/send-globe-key-action/38681/4">u</a><a target="_blank" href="https://forums.macrumors.com/threads/function-key-globe-key-as-shortcut.2470194/">s</a><a target="_blank" href="https://discussions.apple.com/thread/256209007?sortBy=rank">i</a><a target="_blank" href="https://apple.stackexchange.com/questions/437454/use-fn-key-as-globe-key-on-first-generation-magic-keyboard">o</a><a target="_blank" href="https://talk.macpowerusers.com/t/function-key-as-globe-or-augmenting-key-on-mac/23903">n</a> in forums around Fn and Globe keys. My brand-new portable Logitech keyboard has a  key that works when I pair it to my iPad, but doesn’t when it’s connected to some of my Macs. No Globe shortcuts work via remote desktop or in simulators. Most external keyboards don’t support any of them – and if it’s possible to make it happen for a few, it requires third-party software and <a target="_blank" href="https://aresluna.org/fn/how-to-make-fn-globe-key-work/">two journeys to two different keyboard underworlds</a>.</p><p>In one thread, I saw this comment: “The Globe key doesn't work when the lid is closed, but it does work when the lid is open.” I believe it.</p><p>Even on Apple’s keyboards, why are Fn/Globe symbols swapped visually compared to everything else? And does Apple really plan eventually to put a “globe” text label next to it?</p><div class="figure-group width-chute-narrow mobile-bleed"><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/flipped-1.avif" alt="image" /></figure><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/flipped-2.avif" alt="image" /></figure></div><hr /><h3 class="number">6</h3><p>Okay, keyboard nerd. Relax. It’s just a modifier key. Why are you so worked up about it? If you don’t like it, don’t use it.</p><p>This matters to me and feels bigger than just Fn, because I know keyboards can help you use your computer in better ways than you might imagine.</p><p>Doug Engelbart’s demos, combined with experiences of typists and musicians before him, showed us that this actually works. That you can offload a lot of menial stuff to faraway parts of your brain. That you can use your keyboard and achieve flow without thinking about what you’re doing. A lot of us no longer consciously perceive ⌘Z or the beautiful duo of ⌘C and ⌘V – they’re just things our fingers do without us thinking. Many other keyboard shortcuts and interactions can feel that way, unlocking new and better ways to use your computer.</p><p>But this cannot happen with millions of modifier keys packed like sardines in a box. Early electronic typewriters from IBM understood it with large keys like Code, and NeXT in 1992 even experimented with a long ⌘ bar below the spacebar for the same reason.</p><div class="figure-group width-chute mobile-bleed"><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/ibm-next/ibm.avif" alt="image" /></figure><figure class="aspect-square"><img src="https://aresluna.org/fn/images/fn/ibm-next/next.avif" alt="image" /></figure></div><p>But look what happened to the Mac since 1986:</p><figcaption>Mac Plus in 1986 and Apple desktop keyboards in 2015 and 2025</figcaption><p>Today, the space around space is a zero-sum game. Purely ergonomically, Fn makes the other keys smaller and harder to press. On smaller keyboards, the modifiers are now more narrow than regular keys, and yet are still meant to be pressed either with the least precise thumb or with other fingers travelling far frm the home row. On Apple’s official Japanese desktop keyboard, Fn even has to be put on the right just because there is no room for it on the left.</p><div class="figure-group width-chute-narrow mobile-bleed"><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/logitech-to-go.avif" alt="image" /></figure><figure class="aspect-landscape"><img src="https://aresluna.org/fn/images/fn/fn-japanese.avif" alt="image" /></figure></div><p>But it’s not just ergonomics. One new of <a target="_blank" href="https://unsung.aresluna.org/this-cognitive-load-is-invisible-and-rarely-discussed/">anything</a> means more cognitive load. Fluid and natural keyboard use cannot blossom when a system of modifiers and shortcuts is confusing, inconsistent even between platforms that Apple controls, and when any time you use a third-party keyboard, some keys are unavailable, and some menus lie to you.</p><p>How can you trust a system that doesn’t fully work? How can you understand a system that doesn’t understand itself?</p><p>“Don’t use it if you don’t like it” doesn’t magically make the other keys bigger, or reduce confusion. The forum complains continue, and even Apple experts struggle to make sense. A 2021 <a target="_blank" href="https://sixcolors.com/post/2021/06/think-globally-the-ipads-new-universal-keyboard-shortcuts/">article about the Globe key</a> speculated that it will take over multimedia transport controls (instead, the next Magic Keyboard simply resurrected the function key row at the top), and that it will soon allow user shortcuts…</p><p>…which apparently is possible in Shortcuts on a Mac! I can assign a Shortcut to Y which feels like it shouldn’t be allowed, but it is:</p><figure class="width-chute-narrow image-transparent mobile-bleed"><img data-width="1724" data-height="1140" src="https://aresluna.org/fn/images/fn/shortcuts.avif" alt="image" /></figure><p>…and yet, at the same time, I cannot assign it to H. So, who’s in control here? What if Apple at some point grabs Y for some new feature? Would my shortcut and the motor memory attached to it just be thrown away?</p><p>And why doesn’t assigning to  work in other parts of the operating system? Is the above meant to be a Shortcuts perk, or is it a mistake? If the former: why? If the latter: how? Apple talks so little about the keys and updates their docs so rarely that I genuinely have no idea.</p><hr /><h3 class="number">7</h3><p>This is a mess and I’m angry at Apple about it.</p><p>iPad simply doesn’t need five modifier keys downwind from the spacebar. I would argue even Mac doesn’t. I know that shortcut transitions are hell, and motor memory of your userbase a cruel force to be reckoned with, but this is undoable. Moving even <a target="_blank" href="https://www.macworld.com/article/172146/tactilepro.html">an aircraft carrier</a> is possible – it just takes a careful many years of planning and execution. Of all companies today, Apple is perhaps the only one that could shepherd that transition.</p><p>And I also believe keyboard reinvention is necessary over time. Our usage patterns change. No one mourns Insert. Microsoft cleverly reused PrtSc to be a screenshot-taking key. So many people begin and end on smaller keyboards today that they might just not know about PgUp, or Home, or Forward Delete, the once ghosted keys that are possibly effectively completely dead.</p><p>But Apple, come on. Not like this. We’re here <em>14 years</em> after you started tinkering with the Fn key, and it’s a mess bigger than ever. There seems to be no larger plan, and every few years starting with 1986, we get another perplexing and shortsighted decision.</p><p>You want to hear something funny? There existed some Fn keys before PCjr, and one of them was on a British computer called Acorn Electron, released in 1983. It wasn’t there to approximate other keys, but to do something more like what Apple wants to do with  today – to speed up issuing commands.</p><p>And you know where Acorn put it? They colocated it on the Caps Lock key, because even in 1983, we already knew Caps Lock didn’t deserve the large size nor the <a target="_blank" href="https://en.wikipedia.org/wiki/Billionaires%27_Row">Central Park-adjacent location</a> for whatever it offered.</p><figure class="width-chute aspect-landscape-21 mobile-bleed"><img src="https://aresluna.org/fn/images/fn/acorn-electron.avif" alt="image" /></figure><p>This was one solution, right here, that was staring Apple in the face all along. Get rid of Control and Fn, and repurpose Caps Lock as a system shortcut. There are other approaches, too. None of them are easy or fast, but that shouldn’t be an excuse.</p><p>I know Apple doesn’t consider hardware keyboard too worthy of innovation; the venerable slab of QWERTY never appears next to iPod’s wheel and multitouch on the list of input breakthroughs they’re proud of, and the only interesting physical Apple keyboard was 1993’s <a target="_blank" href="https://en.wikipedia.org/wiki/Apple_Adjustable_Keyboard">Adjustable</a>.</p><p>But this isn’t about innovation. Keyboards aren’t going away. This is, at this point, proper maintenance, dealing with self-imposed complexity, and respect for an input method that we know can give so much back.</p><p>There was a time when Acorn, creators of <a target="_blank" href="https://en.wikipedia.org/wiki/Acorn_Computers#/media/File:Acorn_8-bit_microcomputers.jpg">generally beloved computers</a>, was called “the British Apple.” Apple, you’re breaking my heart with all this keyboard stuff, and so I’m telling you this with spite: You can do it. If you apply yourself, you can become the American Acorn.</p>]]></description>
      <link>https://aresluna.org/fn/</link>
      <guid>https://aresluna.org/fn/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Getting Started with Common Lisp]]></title>
      <description><![CDATA[<p>An easy way to start with Lisp-Stat</p><p><time datetime="2026-03-09" class="text-body-secondary">Monday, 09 March 2026</time></p><p>It’s never been easy for a developer to get started in Common Lisp. Emacs, though a powerful editor, isn’t considered an IDE by modern standards. Setting up a compiler, quicklisp, slime, swank, and then learning an entirely new programming paradigm has scared off many would-be entrants to the Common Lisp community.</p><p>Given the size of the Common Lisp community this is understandable. Making the new user experience smooth and frictionless as possible is <em>hard work</em>. It’s the kind of work that no one volunteers for; it’s the kind of work you have to be <em>paid</em> for.</p><p>Still, it’s a pre-requisite for new users, so I’ve created <a href="https://github.com/Lisp-Stat/ls-dev-image">ls-dev-image</a>, a ‘batteries included’ OCI image for Lisp-Stat or just plain Common Lisp development. Assuming you have an OCI (e.g Docker) runtime installed. Here’s how to get started.</p><h2 id="shell">Shell</h2><div class="highlight"><pre class="language-sh" data-lang="sh">docker run --rm -it --user vscode -w /home/vscode ghcr.io/lisp-stat/ls-dev:latest bash
</pre></div><p>Now you’re in the container with a <code>bash</code> shell and can configure the machine as you like.</p><h2 id="common-lisp-repl">Common Lisp REPL</h2><p>If you want a Common Lisp REPL:</p><div class="highlight"><pre class="language-sh" data-lang="sh">docker run --rm -it --user vscode -w /home/vscode ghcr.io/lisp-stat/ls-dev:latest ls-repl
</pre></div><p>and you should see:</p><pre>Linedit version 0.17.6, smart mode, ESC-h for help.
CL-USER(1):
</pre><p>You could also have gotten here from the shell with the <code>sbcl</code> command. This is a bare common lisp image, with nothing loaded. Now you load lisp-stat from the Quicklisp repositories with:</p><pre>(ql:quickload :lisp-stat)
... lot's of compilation output ...
[package ls-user]
(:LISP-STAT)
CL-USER(2):
</pre><p>and to start working with Lisp-Stat:</p><div class="highlight"><pre class="language-lisp" data-lang="lisp">(in-package :ls-user
</pre></div><p>This REPL has been configured with a few packages to make it easier to work with.</p><ul><li><a href="https://github.com/sharplispers/linedit">linedit</a>, provides customizable line-editing. You can use emacs key bindings to edit the REPL commands.</li>
<li><a href="https://www.sbcl.org/manual/#sb_002daclrepl">Acl-repl</a> is a SBCL extension that gives you command history (via up/down arrows) and some short command codes such as <code>:cs</code> for <code>compile-system</code>, <code>:ts</code> for <code>test-system</code>, etc.</li>
</ul><p>Generally you won’t be doing development with the REPL, you’ll be doing it in emacs.</p><h2 id="emacsslime">Emacs/Slime</h2><p>Now you can use Common Lisp with emacs, quicklisp and slime. From the shell you can type ’emacs’ followed by ‘M-x slime’ and start hacking Common Lisp.</p><img width="1306" height="762" alt="image" src="https://github.com/user-attachments/assets/1abaeea4-1bee-494b-9dd4-c590c9a66f5c" /><p>The upstream repositories are often out of date. To get the latest and to keep them synced you can use the <code>init.sh</code> script with <code>ls-init.sh --mode experimenter</code>. Experimenter will download the repos so you can try out the source code, but you won’t be able to push your changes or make pull requests. For that you want to be a ‘contributor’: <code>ls-init.sh --mode contributor</code>.</p><p>Now when you start <code>ls-repl</code> you should see the lisp-stat REPL prompt, indicating you’re in the <code>LS-USER</code> package:</p><div class="highlight"><pre class="language-sh" data-lang="sh">ls-init.sh --mode experimenter
# ... output from repo checkouts, linking, configuration
</pre></div><div class="highlight"><pre class="language-sh" data-lang="sh">ls-repl
</pre></div><p>lot’s of recompilation because you’re now using local source repos and then:</p><pre>...
To load "ls-server":
  Load 1 ASDF system:
    ls-server
; Loading "ls-server"
.....
Linedit version 0.17.6, smart mode, ESC-h for help.
LS-USER(1):
</pre><p>From here <code>emacs</code> and <code>M-x slime</code> (from the shell) will load Lisp-Stat.</p><h2 id="ls-server">LS-Server</h2><p>A <a href="https://github.com/Lisp-Stat/ls-server">ls-server</a> is also configured to start automatically on port 20202. If you open your browser and point it to https://localhost:20202 (or other port, depending on your OCI container configuration) you’ll see the web interface for displaying plots and viewing/editing data-frames.</p><img width="1038" height="704" alt="image" src="https://github.com/user-attachments/assets/98c0e707-b259-48e4-93c1-1ba7f62e3f09" /><p>You can also run this OCI image in GitHub codespaces.</p><p>You will want to run <code>docker pull</code> occasionally to get the latest <code>ls-dev-image</code>. This should stabilize in a month or so and after that it won’t need to be updated frequently. To keep lisp-stat source in sync, run <code>ls-init.sh --refresh</code>. If you want help with <code>ls-init.sh</code>, run <code>ls-init.sh --help</code>.</p><p>Contributions and <a href="https://github.com/Lisp-Stat/ls-dev-image/issues">bug reports</a> are welcome and encouraged.</p><ul class="list-unstyled d-flex justify-content-between align-items-center mb-0 pt-5"><li><a href="https://lisp-stat.dev/blog/2023/12/29/2023-end-of-year-summary/" aria-label="Previous - 2023 End of Year Summary" class="btn btn-primary">←Previous</a></li>
<li><a class="btn btn-primary disabled">Next→</a></li>
</ul><p>Last modified 11 March 2026: <a data-proofer-ignore="" href="https://github.com/Lisp-Stat/documentation/commit/e022fab352070927b5fed7047d1eddac4125d899">Reorganise, improve clarity (e022fab)</a></p>]]></description>
      <link>https://lisp-stat.dev/blog/2026/03/09/getting-started/</link>
      <guid>https://lisp-stat.dev/blog/2026/03/09/getting-started/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[No, it doesn't cost Anthropic $5k per Claude Code user]]></title>
      <description><![CDATA[<p>My LinkedIn and Twitter feeds are full of screenshots from the recent <a href="https://www.forbes.com/sites/annatong/2026/03/05/cursor-goes-to-war-for-ai-coding-dominance/">Forbes article on Cursor</a> claiming that Anthropic's $200/month Claude Code Max plan can consume $5,000 in compute. The relevant quote:</p><blockquote>
<p>Today, that subsidization appears to be even more aggressive, with that $200 plan able to consume about $5,000 in compute, according to a different person who has seen analyses on the company's compute spend patterns.</p>
</blockquote><p>This is being shared as proof that Anthropic is haemorrhaging money on inference. It doesn't survive basic scrutiny.</p><h2>What the $5,000 figure actually is</h2><p>I'm fairly confident the Forbes sources are confusing <em>retail API prices</em> with <em>actual compute costs</em>. These are very different things.</p><p>Anthropic's current API pricing for Opus 4.6 is $5 per million input tokens and $25 per million output tokens. At those prices, yes - a heavy Claude Code Max 20 user could rack up $5,000/month in API-equivalent usage. That maths checks out.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p><p>But API pricing is not what it costs Anthropic to serve those tokens.</p><h2>The OpenRouter reality check</h2><p>The best way to estimate what inference actually costs is to look at what open-weight models of similar size are priced at on OpenRouter - where multiple providers compete on price.</p><p>Qwen 3.5 397B-A17B is a good comparison point. It's a large MoE model, broadly comparable in architecture size to what Opus 4.6 is likely to be. Equally, so is Kimi K2.5 1T params with 32B active, which is probably approaching the upper limit of what you can efficiently serve.</p><p>Here's what the pricing looks like:</p><img src="https://martinalderson.com/img/openrouter-qwen-opus-pricing.png" alt="OpenRouter pricing showing Qwen 3.5 397B and Kimi K2.5 at roughly 10% of Claude Opus 4.6 API pricing per token" class="no-border c1" />The Qwen 3.5 397B model on OpenRouter (via Alibaba Cloud) costs _$0.39_ per million input tokens and _$2.34_ per million output tokens. Compare that to Opus 4.6's API pricing of $5/$25. Kimi K2.5 is even cheaper at $0.45 per million input tokens and $2.25 output.<p>That's roughly <em>10x cheaper</em>.</p><p>And this ratio holds for cached tokens too - DeepInfra charges $0.07/MTok for cache reads on Kimi K2.5 vs Anthropic's $0.50/MTok.</p><p>These OpenRouter providers are running a business. They have to cover their compute costs, pay for GPUs, and make a margin. They're not charities. If so many can serve a model of comparable size at ~10% of Anthropic's API price and remain in business, it is hard for me to believe that they are all taking enormous losses (at ~the exact same rate range).</p><p>If a heavy Claude Code Max user consumes $5,000 worth of tokens at Anthropic's <em>retail API prices</em>, and the actual compute cost is roughly 10% of that, Anthropic is looking at approximately $500 in real compute cost for the heaviest users.</p><p>That's a loss of $300/month on the most extreme power users - not $4,800.</p><p>However, <em>most</em> users don't come anywhere near the limit. Anthropic themselves said when they introduced weekly caps that <a href="https://techcrunch.com/2025/07/28/anthropic-unveils-new-rate-limits-to-curb-claude-code-power-users/">fewer than 5% of subscribers would be affected</a>. I personally use the Max 20x plan and probably consume around 50% of my weekly token budget and it's <em>hard</em> to use that many tokens without getting serious RSI. At that level of usage, the maths works out to roughly break-even or profitable for Anthropic. <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p><h2>So who is actually losing $5,000?</h2><p>The real story is actually in the article. The $5,000 figure comes from <em>Cursor's internal analysis</em>. And for Cursor, the number probably <em>is</em> roughly correct - because Cursor has to <em>pay Anthropic's retail API prices</em> (or close to it) for access to Opus 4.6.</p><p>So to provide a Claude Code-equivalent experience using Opus 4.6, it would cost <em>Cursor</em> ~$5,000 per power user per month. But it would cost <em>Anthropic</em> perhaps $500 max.</p><p>And the real issue for Cursor is that developers <em>want</em> to use the Anthropic models, even in Cursor itself. They have real "brand awareness", and they are genuinely better than the cheaper open weights models - for now at least. It's a <a href="https://techcrunch.com/2025/07/07/cursor-apologizes-for-unclear-pricing-changes-that-upset-users/">real conundrum</a> for them.</p><h2>Anthropic is not a profitable company. But inference isn't why.</h2><p>Obviously Anthropic isn't printing free cashflow. The costs of training frontier models, the enormous salaries required to hire top AI researchers, the multi-billion dollar compute commitments - these are genuinely massive expenses that dwarf inference costs.</p><p>But on a per-user, per-token basis for inference? I believe Anthropic is very likely profitable - potentially <em>very</em> profitable - on the average Claude Code subscriber.</p><p>The "AI inference is a money pit" narrative is misinformation that actually plays into the hands of the frontier labs. If everyone believes that serving tokens is wildly expensive, nobody questions the 10x+ markups on API pricing. It discourages competition and makes the moat look deeper than it is.</p><p>If you want to understand the real economics of AI inference, don't take API prices at face value. Look at what competitive open-weight model providers charge on OpenRouter. That's a much closer proxy for what it actually costs to run these models - and it's a fraction of what the frontier labs charge.</p><hr class="footnotes-sep" /><section class="footnotes"><ol class="footnotes-list"><li id="fn1" class="footnote-item">
<p>A HN user claimed they were burning 150M-200M tok/day. Assuming a 95% cache hit rate and a 90% input/output ratio, this works out at somewhere between $400-$600/day in "API" costs, which is pretty much bang on the $5,000/month estimate ($4,200-$6,000). I got the cache hit rate stats and input/output breakdown from <a href="https://amanhimself.dev/blog/claude-code-tokens-usage/">this blog</a> and scaled it up for that usage. <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item">
<p>According to Anthropic's own <code>/cost</code> <a href="https://code.claude.com/docs/en/costs">command data</a>, the average Claude Code developer uses about <em>$6/day in API-equivalent spend</em>, with 90% under $12/day. That's $180/month average. At 10% actual cost, that's <em>$18/month</em> to serve - against a $20-200 subscription. <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol></section>]]></description>
      <link>https://martinalderson.com/posts/no-it-doesnt-cost-anthropic-5k-per-claude-code-user/</link>
      <guid>https://martinalderson.com/posts/no-it-doesnt-cost-anthropic-5k-per-claude-code-user/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How the FTC Head Is Rewriting the Playbook for Policing Companies in Trump 2.0 - WSJ]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.wsj.com/us-news/law/trump-ftc-andrew-ferguson-2aa72f17</link>
      <guid>https://www.wsj.com/us-news/law/trump-ftc-andrew-ferguson-2aa72f17</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Meta acquires Moltbook, the Reddit-like network for AI agents | The Verge]]></title>
      <description><![CDATA[<div class="duet--article--lede duet--page-layout--standard-article duet--ledes--standard-lede _1o1f7ku0 _1ymtmqp3">
<div class="_1o1f7ku1 _1o1f7ku2 _1p1nf4x0">
<div class="">
<p class="duet--article--dangerously-set-cms-markup _8enl99h _8enl99g _1xwticta _1xwtict1">The Moltbook team is joining Meta’s AI division.</p>
</div>
</div>
<div class="_1o1f7ku6">
<div class="_1o1f7ku7">
<div class="_1o1f7ku3 _1o1f7ku9 _13g9mks1 _13g9mks0">
<div class="_13g9mks9">
<time datetime="2026-03-10T15:22:17+00:00">Mar 10, 2026, 3:22 PM UTC</time></div>
</div>
</div>
<div class="_1o1f7ku4 _1ibjt4j0 duet--layout--entry-image _1b9pgly0">
<div class="_1b9pgly1 _1b9pgly2">
<div class="_1ymtmqpn _1ymtmqpx"><img alt="STK414_AI_CVIRGINIA_C" data-chromatic="ignore" data-nimg="fill" class="x271pn0 c5" sizes="(max-width: 768px) 100vw, 700px" srcset="https://platform.theverge.com/wp-content/uploads/sites/2/2025/03/STK414_AI_CVIRGINIA_C.jpg" src="https://platform.theverge.com/wp-content/uploads/sites/2/2025/03/STK414_AI_CVIRGINIA_C.jpg" /></div>
</div>
<div class="duet--media--caption qama0i0"><cite class="duet--article--dangerously-set-cms-markup _1xwtict2 qama0i5">Image: Cath Virginia / The Verge, Getty Images</cite></div>
</div>
</div>
</div><div class="duet--layout--entry-body-container _1t5ltw90 _1ymtmqp3 _1ymtmqp14 _1t5ltw91">
<div class="duet--layout--entry-body _9f4de40">
<div id="zephr-anchor" class="_1ymtmqp11">
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Meta is acquiring Moltbook, a Reddit-like platform where AI agents can make and comment on posts, <a href="https://www.axios.com/2026/03/10/meta-facebook-moltbook-agent-social-network">as first reported by <em>Axios</em></a>. In a statement to <em>The Verge</em>, Meta spokesperson Matthew Tye confirmed the Moltbook team will join Meta Superintelligence Labs as the company looks for “new ways for AI agents to work for people and businesses.”</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Matt Schlicht and Ben Parr launched Moltbook earlier this year, offering a “social” network for autonomous agents powered by the open-source AI assistant OpenClaw (formerly Moltbot). The platform went viral earlier this year for a number of posts — including <a href="http://moltbook.com/post/6fe6491e-5e9c-4371-961d-f90c4d357d0f">one that asks questions about AI consciousness</a> — though experts found <a href="https://www.theverge.com/ai-artificial-intelligence/872961/humans-infiltrating-moltbook-openclaw-reddit-ai-bots">that humans may have been behind the posts</a> that received the most attention.</p>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Researchers also discovered a now-fixed <a href="https://www.wiz.io/blog/exposed-moltbook-database-reveals-millions-of-api-keys">security flaw that exposed API keys</a> and allowed <a href="https://www.404media.co/exposed-moltbook-database-let-anyone-take-control-of-any-ai-agent-on-the-site/">people to take control of any AI agent</a> on the platform. Meta’s acquisition of Moltbook will allow the company to “bring innovative, secure agentic experiences to everyone,” Tye said.</p>
</div>
<div class="duet--article--block-placement _1o279nj1 _1o279nj0 duet--article--article-body-component duet--article--related _1ymtmqpj _1m6r73h0">
<h3 class="_1m6r73h1">Related</h3>
</div>
<div class="duet--article--article-body-component">
<p class="duet--article--dangerously-set-cms-markup duet--article--standard-paragraph _1ymtmqpi _17nnmdy1 _17nnmdy0 _1xwtict1">Moltbook’s acquisition comes just weeks <a href="https://www.theverge.com/ai-artificial-intelligence/879623/openclaw-founder-peter-steinberger-joins-openai">after OpenAI hired OpenClaw founder Peter Steinberger</a>. It’s not clear what the future of Moltbook will look like, as Meta VP Vishal Shah says in an internal memo cited by <em>Axios</em> that existing users can keep using Moltbook, but “signaled the arrangement is temporary.”</p>
</div>
</div>
</div>
<div class="duet--layout--rail _1xql9yl0 _1xql9yl1">
<div class="_1xql9yl2 _1xql9yl6 _1xql9yl8">
<form class="a18g6g0 _1ymtmqpz _1ymtmqpj a18g6g5" action="action">
<div class="duet--cta--newsletter a18g6g9">
<div class="a18g6gd">
<h2 class="a18g6gh">The Verge Daily</h2>
<p class="a18g6gi">A free daily digest of the news that matters most.</p>
</div>
<div class="a18g6gy a18g6gz">
<fieldset><div class="a18g6g12 a18g6g11">
<div class="a18g6g16 a18g6g1e duet--cta--form-field-text _1i902bu0"><label for="email" class="_1pbfapu0 _1yjvsxi0">Email (required)</label>
</div>
</div>
</fieldset><div class="a18g6g1q a18g6gj">By submitting your email, you agree to our <a href="https://www.voxmedia.com/legal/terms-of-use" class="a18g6g1p">Terms</a> and <a href="https://www.voxmedia.com/legal/privacy-notice" class="a18g6g1p">Privacy Notice</a>. This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy" class="a18g6g1p">Privacy Policy</a> and <a href="https://policies.google.com/terms" class="a18g6g1p">Terms of Service</a> apply.</div>
</div>
</div>
</form>
</div>
</div>
</div>]]></description>
      <link>https://www.theverge.com/ai-artificial-intelligence/892178/meta-moltbook-acquisition-ai-agents</link>
      <guid>https://www.theverge.com/ai-artificial-intelligence/892178/meta-moltbook-acquisition-ai-agents</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[After outages, Amazon to make senior engineers sign off on AI-assisted changes - Ars Technica]]></title>
      <description><![CDATA[<header><div class="dusk:bg-gray-700 my-4 bg-gray-100 pt-2 md:mt-10 md:pt-5 lg:pb-2 lg:pt-7 dark:bg-gray-700">
  <div class="mx-auto grid-cols-2 gap-8 md:px-5 lg:grid lg:max-w-5xl lg:px-8 xl:px-0">
    <div class="">
      
      
      <p class="text-gray-550 dark:text-gray-250 dusk:text-gray-250 mt-4 px-[15px] text-lg leading-tight sm:px-5 md:px-0">
        AWS has suffered at least two incidents linked to the use of AI coding assistants.
      </p>
              
          </div>
    <div class="mt-4 min-h-1 lg:mt-0">
              <div class="relative aspect-video overflow-hidden">
                      <div class="ars-lightbox">
              <div class="ars-lightbox-item">
                <a class="cursor-zoom-in" data-pswp-width="2560" data-pswp-height="1706" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-scaled.jpg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-300x200.jpg 300w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-640x427.jpg 640w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-768x512.jpg 768w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1536x1024.jpg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-2048x1365.jpg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-980x653.jpg 980w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1440x960.jpg 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-scaled.jpg" target="_blank">
                  <img width="300" height="200" src="https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-300x200.jpg" class="absolute inset-0 w-full h-full object-cover hidden" alt="Exterior of large building during daytime." srcset="https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-300x200.jpg 300w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-640x427.jpg 640w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-768x512.jpg 768w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1536x1024.jpg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-2048x1365.jpg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-980x653.jpg 980w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1440x960.jpg 1440w" sizes="(max-width: 300px) 100vw, 300px" /><img width="1152" height="648" src="https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1152x648.jpg" class="intro-image absolute min-w-full min-h-full h-auto object-cover" alt="Exterior of large building during daytime." srcset="https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1152x648.jpg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-384x216.jpg 384w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-768x432.jpg 768w, https://cdn.arstechnica.net/wp-content/uploads/2019/09/GettyImages-1157406884-1536x864.jpg 1536w" sizes="(max-width: 1152px) 100vw, 1152px" /></a>
                
              </div>
            </div>
        </div>
        <div class="px-[15px] sm:px-5 md:px-0"><div class="caption font-impact dusk:text-gray-300 mb-4 mt-2 inline-flex flex-row items-stretch gap-1 text-base leading-tight text-gray-400 dark:text-gray-300">
    
    <div class="caption-content">
      The Amazon logo at the entrance of a logistics center in France, July 2019.
              
          Credit:
                      <a class="caption-credit-link text-gray-400 no-underline hover:text-gray-500" href="https://www.gettyimages.com/detail/news-photo/picture-shows-the-amazon-logo-at-the-entrance-of-the-amazon-news-photo/1157406884" target="_blank">
          Denis Charlet | AFP | Getty 
                      </a>
                  
          </div>
  </div></div>
          </div>
  </div>
</div>
</header><div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
          <p>Amazon’s ecommerce business has summoned a large group of engineers to a meeting on Tuesday for a “deep dive” into a spate of outages, including incidents tied to the use of AI coding tools.</p>
<p>The online retail giant said there had been a “trend of incidents” in recent months, characterized by a “high blast radius” and “Gen-AI assisted changes” among other factors, according to a briefing note for the meeting seen by the FT.</p>
<p>Under “contributing factors” the note included “novel GenAI usage for which best practices and safeguards are not yet fully established.”</p>
<p>“Folks, as you likely know, the availability of the site and related infrastructure has not been good recently,” Dave Treadwell, a senior vice-president at the group, told employees in an email, also seen by the FT.</p>
<p>The note ahead of Tuesday’s meeting did not specify which particular incidents the group planned to discuss.</p>
<p>Amazon’s website and shopping app went down for nearly six hours this month in an incident the company said involved an erroneous “software code deployment.” The outage left customers unable to complete transactions or access functions such as checking account details and product prices.</p>
<p>Treadwell, a former Microsoft engineering executive, told employees that Amazon would focus its weekly “This Week in Stores Tech” (TWiST) meeting on a “deep dive into some of the issues that got us here as well as some short immediate term initiatives” the group hopes will limit future outages.</p>
                      
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="mt-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>He asked staff to attend the meeting, which is normally optional.</p>
<p>Junior and mid-level engineers will now require more senior engineers to sign off any AI-assisted changes, Treadwell added.</p>
<p>Amazon said the review of website availability was “part of normal business” and it aims for continual improvement.</p>
<p>“TWiST is our regular weekly operations meeting with a specific group of retail technology leaders and teams where we review operational performance across our store,” the company said.</p>
<p>Separately, the company’s cloud computing arm—Amazon Web Services—has suffered at least two incidents linked to the use of AI coding assistants, which the company has been actively rolling out to its staff.</p>
<p>AWS suffered a 13-hour interruption to a cost calculator used by customers in mid-December after engineers allowed the group’s Kiro AI coding tool to make certain changes, and the AI tool opted to “delete and recreate the environment,” the FT previously reported.</p>
<p>Amazon previously said the incident in December was an “extremely limited event” affecting only a single service in parts of mainland China. Amazon added that the second incident did not have an impact on a “customer facing AWS service.”</p>
<p>The FT previously reported multiple Amazon engineers said their business units had to deal with a higher number of “Sev2s”—incidents requiring a rapid response to avoid product outages—each day as a result of job cuts.</p>
<p>Amazon has undertaken multiple rounds of lay-offs in recent years, most recently eliminating 16,000 corporate roles in January. The group has disputed the claim that headcount cuts were responsible for an increase in recent outages.</p>
<p><em><a href="https://www.ft.com/">© 2026 The Financial Times Ltd</a>. <a href="https://www.ft.com">All rights reserved</a>. Not to be redistributed, copied, or modified in any way.</em></p>
                  </div>
          
  
  
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>]]></description>
      <link>https://arstechnica.com/ai/2026/03/after-outages-amazon-to-make-senior-engineers-sign-off-on-ai-assisted-changes/</link>
      <guid>https://arstechnica.com/ai/2026/03/after-outages-amazon-to-make-senior-engineers-sign-off-on-ai-assisted-changes/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Dokploy - Effortless Deployment Solutions]]></title>
      <description><![CDATA[<div class="h-[1100px] bg-black pt-20 sm:h-[1100px] lg:pt-32 bottom-0 flex w-full items-center justify-center overflow-hidden rounded-lg bg-background md:shadow-xl"><div class="relative px-4"><div class="text-center"><p class="mx-auto mt-6 max-w-2xl text-lg tracking-tight text-muted-foreground c3">Manage containerized deployments across multiple servers with ease thanks to our all-in-one platform for developers.</p><div class="flex flex-col items-center justify-center space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0 flex flex-col gap-6 c4"><div class="mt-6 flex flex-wrap items-center justify-center gap-6 md:flex-nowrap"><code class="flex flex-row items-center gap-4 rounded-xl border p-3 font-sans">curl -sSL https://dokploy.com/install.sh | sh</code></div><p><a aria-label="Dokploy on GitHub" target="_blank" class="inline-flex items-center justify-center whitespace-nowrap text-sm will-change-transform transition-all active:hover:scale-[0.98] font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2 w-full rounded-full flex flex-row items-center gap-2" href="https://github.com/dokploy/dokploy">GitHub</a><a aria-label="Dokploy on GitHub" target="_blank" class="inline-flex items-center justify-center whitespace-nowrap text-sm will-change-transform transition-all active:hover:scale-[0.98] font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 text-primary-foreground h-10 px-4 py-2 w-full rounded-full bg-[#5965F2] hover:bg-[#4A55E0] flex flex-row items-center gap-2 text-white" href="https://discord.gg/2tBnJ3jDJc">Discord</a></p></div></div><div class="mx-auto mt-10 max-w-2xl mt-10 flex flex-row justify-center gap-x-8 rounded-lg sm:gap-x-0 sm:gap-y-10 xl:gap-x-12 xl:gap-y-0 relative block w-full max-w-md rounded-xl group relative cursor-pointer c4"><img src="https://dokploy.com/banner.png" alt="Hero Video" width="1920" height="1080" class="w-full rounded-md border shadow-lg transition-all duration-200 ease-out group-hover:brightness-[0.8]" /></div></div></div><div class="mt-20 flex flex-col items-center justify-center px-4"><h2 class="text-center font-display text-3xl tracking-tight text-primary sm:text-4xl">Powerful Deployment Tailored to You</h2><p class="mt-4 text-center text-lg tracking-tight text-muted-foreground">Unlock seamless multi-server deployments, advanced user control, and flexible database management—all with Dokploy’s developer-focused features.</p><div class="relative z-10 mx-auto mt-10 grid max-w-7xl grid-cols-1 py-10 max-sm:mx-0 max-sm:w-full max-sm:p-0 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r lg:border-l dark:border-neutral-800 lg:border-b"><p>Flexible Application Deployment</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Deploy any application using Nixpacks, Heroku Buildpacks, or your custom Dockerfile, tailored to your stack.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-b"><p>Native Docker Compose Support</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Deploy complex applications natively with full Docker Compose integration for seamless orchestration.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-b"><p>Multi-server Support</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Effortlessly deploy your applications on remote servers, with zero configuration hassle.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-b"><p>Advanced User Management</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Control user access with detailed roles and permissions, keeping your deployments secure and organized.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r lg:border-l dark:border-neutral-800 lg:border-b"><p>Database Management with Backups</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Manage and back up MySQL, PostgreSQL, MongoDB, MariaDB, Redis directly from Dokploy.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-b"><p>API &amp; CLI Access</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Need custom functionality? Dokploy offers complete API and CLI access to fit your needs.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-b"><p>Docker Swarm Clusters</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Scale your deployments seamlessly with built-in Docker Swarm support for robust, multi-node applications.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-b"><p>Open Source Templates</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Get started quickly with pre-configured templates for popular tools like Supabase, Cal.com, and PocketBase.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r dark:border-neutral-800 lg:border-l"><p>No Vendor Lock-In</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Experience complete freedom to modify, scale, and customize Dokploy to suit your specific needs.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r"><p>Real-time Monitoring &amp; Alerts</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Monitor CPU, memory, and network usage in real-time across your deployments for full visibility.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r"><p>Built for Developers</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Designed specifically for engineers and developers seeking control and flexibility.</p></div><div class="group/feature relative flex flex-col border-neutral-800 py-10 lg:border-r"><p>Self-hosted &amp; Open Source</p><p class="relative z-10 px-10 text-sm text-neutral-300 lg:max-w-xs">Dokploy provides complete control with self-hosting capabilities and open-source transparency.</p></div></div></div>
<div class="flex flex-col gap-10 px-4 py-20 lg:py-40"><div class="mx-auto max-w-2xl md:text-center"><h2 class="text-center font-display text-3xl tracking-tight sm:text-4xl">Stats You Didn't Ask For (But Secretly Love to See)</h2><p class="mt-4 text-center text-lg tracking-tight text-muted-foreground">Just a few numbers to show we're not *completely* making this up. Turns out, Dokploy has actually helped a few people—who knew?</p></div></div>
<section id="testimonials" aria-label="What our customers are saying" class="py-20 sm:py-32"><div class="mx-auto max-w-2xl px-4 md:text-center"><h2 class="text-center font-display text-3xl tracking-tight sm:text-4xl">Why Developers Love Dokploy</h2><p class="mt-4 text-center text-lg tracking-tight text-muted-foreground">Think we’re bragging? Hear from the devs who once doubted too—until Dokploy made their lives (and deployments) surprisingly easier.</p></div></section>]]></description>
      <link>https://dokploy.com/</link>
      <guid>https://dokploy.com/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[AI-powered refund abuse and dispute fraud: The democratization of deception]]></title>
      <description><![CDATA[<section class="section section--with-outside article-header pt-8 pb-6"><div class="container row flex-row-reverse justify-content-end col-lg-9 article__body article__intro text-center fadeIn--elem"><p class="text-uppercase text-md font-weight-semibold d-flex justify-content-center flex-column">Blog / <a href="https://www.ravelin.com/resources?search=&amp;category%5B0%5D=201169#resourceContainer" title="Go to Fraud trends">Fraud trends</a>, <a href="https://www.ravelin.com/resources?search=&amp;category%5B0%5D=204631#resourceContainer" title="Go to Refund abuse">Refund abuse</a></p><p class="article-header__intro faded-blue">Your eyes can no longer be believed. With 65% of consumers saying that AI has made it easier to falsely claim refunds, what can merchants do to protect bottom lines and good customers?</p><p>19 January 2026</p><div class="blog-share my-4 flex flex-column"><p class="text-xs faded-blue mr-3">Share this article:</p></div><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/_blogSmall/273738/461-Refund-abuse-via-GenAI-article-885x505.webp" srcset="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/_blogSmall/273738/461-Refund-abuse-via-GenAI-article-885x505.webp 416w, https://storage.googleapis.com/ravelin-website-assets-production/assets/images/_blogLarge/273738/461-Refund-abuse-via-GenAI-article-885x505.webp 885w" sizes="(max-width: 576px) 416px, 885px" alt="AI-powered refund abuse and dispute fraud: The democratization of deception" class="article-header__img mt-2 mb-4" /></div></section><section class="section blog-content-section pt-0 pb-6"><div class="container row blog-content-wrap blog-toc--hidden"><div class="col-lg-8 article__body order-lg-2 blog-content-col"><div class="article_content faded-blue"><div id="article-section-text-273745" class="article_content__text"><p dir="ltr">There’s no question about it: There’s an emerging threat of <a href="https://www.ravelin.com/blog/refund-abuse-return-fraud">refund abuse</a> powered by sophisticated AI image and video editors.</p><p dir="ltr">Let’s dive into how AI is used for harm by refund abusers and fraudsters, the primary attack methods, and frameworks for detection and prevention.</p><h2 dir="ltr">Digital “proof” created by AI, used for refund abuse</h2><p dir="ltr">A new wave of refund abuse is upon us. Both professional fraudsters and first parties are dipping their toes into the <strong>opportunistic abuse made possible by widely available GenAI models</strong> – such as ChatGPT, Gemini, Claude and others – to realistically edit pictures of products, making them look dirty, torn, broken, damaged or otherwise faulty.</p><p dir="ltr">Ravelin recently discovered that <strong>65% of consumers say that AI has made it easier to falsely claim refunds</strong> for items bought online. The results of this survey of 6200 shoppers, as well as the methodology, were published in the <a href="https://pages.ravelin.com/refund-abuse-trends-report-2026-survey" rel="noopener" target="_blank">State of Refunds 2026 survey report</a>.</p><p dir="ltr">For years, ecommerce businesses have built their customer support and refund processes on a foundation of trust, where a photograph serves as reliable proof of a claim. A customer states an item arrived broken and sends a picture; the case is closed and a refund is issued.</p><p dir="ltr">AI image and video editors fundamentally break this model by attacking its core assumption: that photographic evidence is authentic. <strong>Your eyes can no longer always be believed</strong>.<br /></p></div><div id="article-section-text-273746" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/AI-refund-abuse-vase.png" data-image="273744" alt="AI generates fake cracks in vase for fraud" class="c2" /><figcaption><strong><em>Above, the AI has generated fake cracks and chips in a new vase.</em></strong></figcaption></figure></div><div id="article-section-text-273768" class="article_content__text"><h2 dir="ltr">How AI-powered refund abuse works</h2><p dir="ltr">At its heart, this new wave of refund abuse is driven by a single, powerful principle: <strong>the manipulation of digital evidence submitted to merchants.</strong> The steps can be simple:</p><ol><li dir="ltr">
<p dir="ltr">A customer places an order online.</p>
</li>
<li dir="ltr">
<p dir="ltr">Upon receipt of a satisfactory product, the customer takes a picture of it inside its packaging.</p>
</li>
<li dir="ltr">
<p dir="ltr">The customer uploads the picture to one of several GenAI (generative AI) tools – these can be fraud-specific or generally available, legitimate tools. The prompt requests the addition of tears, open seams, or other issues to the product. This varies depending on the type of product but can include chipping, breaking, tearing, discoloration, etc.</p>
</li>
<li dir="ltr">
<p dir="ltr">The customer files a refund request, providing the generated image as “proof” that their product is problematic.</p>
</li>
</ol><p dir="ltr">From here, it’s possible that the merchant does not request that the product is returned to them.</p><p dir="ltr">Fraudsters know that merchants often have no incentive to have the damaged item returned to them. It’s costly to have shipped back and creates the problem of handling and disposing of an item that can rarely be resold.</p><p dir="ltr">For some items, there is no legitimate way to return – e.g. broken glass and ceramics, food, perishables, electronics with faulty batteries.</p><p dir="ltr">If they are, however, asked to return the product to receive the refund, the fraudster may replace the product with a dummy or bricked product, return an empty box, or otherwise hope their fake return is not identified as such before they receive the money.</p><p>In some cases, it doesn't end with the merchant: <strong>The abusers can file a dispute with their card issuer bank</strong> using the same fake "evidence" even if the merchant rejects their claim.</p><p dir="ltr">This secondary attempt at old-school "<a href="https://www.ravelin.com/blog/criminal-customer-crisis">friendly fraud</a>" will mean a chargeback for the merchant, if the claim gets accepted by the bank.</p></div><div id="article-section-text-273842" class="article_content__text"><figure><a href="https://pages.ravelin.com/refund-abuse-trends-report-2026-survey" target="_blank"><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/Screenshot-2026-01-16-at-13.45.31.png" data-image="273841" alt="Refund abusers use AI" class="c2" /></a>
<figcaption><strong><em>Source: The State of Refund Abuse 2026 report</em></strong></figcaption></figure></div><div id="article-section-text-273770" class="article_content__text"><h2 dir="ltr">How GenAI changed the game for refund abuse: The democratization of deception</h2><p dir="ltr">At the moment, 53% of consumers are experimenting with generative AI, according to <a href="https://www.deloitte.com/us/en/insights/industry/telecommunications/connectivity-mobile-trends-survey.html" rel="noopener" target="_blank">Deloitte</a> – and 59% agree that AI supercharges refund abuse, according to our recent survey.</p><p dir="ltr">For those who like to bend the rules and take advantage of companies, the popularity of these tools has led to a democratization of deception. Previously, creating convincing fake images required significant skill and the ability to use complex software.</p><p dir="ltr">But AI tools make this trivially easy. It’s already more than realistic enough – and it’s only getting better – rapidly so. The results can be achieved in seconds by simply uploading a photo and typing a request. <strong>The tech barrier to committing abuse and fraud has effectively been eliminated.</strong> And <a href="https://pages.ravelin.com/global-fraud-2025-trends-survey" rel="noopener" target="_blank">46% of merchants</a> already voice concerns about AI being weaponized to enable fraud.<br /></p><p dir="ltr">It should also be noted that professional fraudsters are increasingly colluding with consumers to both help them get refunds (for a cut of the profit) and to sell them tech and tools to enable refund abuse.</p><p dir="ltr">As part of this, <a href="https://www.ravelin.com/blog/why-is-fraud-as-a-service-trending">refund-fraud-as-a-service</a> tools seen around the dark web and on social media now include custom AI models which are trained by criminals to achieve more convincing results when generating fake refund evidence.</p><h3 dir="ltr">The photo-as-truth bias</h3><p dir="ltr">Meanwhile, customer service agents are trained to resolve issues quickly, prioritize customer retention and happiness, and are used to accepting photos at face value. They’re looking for visual confirmation of a claim; they’re not conducting forensic analysis of an image file.</p><p dir="ltr">Abusers are exploiting this human element and will continue to do so, knowing “good enough” fake images are likely to pass a quick visual inspection.</p><p dir="ltr">Unfortunately, the processes and setups that exist were implemented back when generative AI images were a dream, not a reality.</p><h3 dir="ltr">Asymmetric risk</h3><p dir="ltr">For the fraudster, the calculation is simple: The cost and effort to generate a fake image are near zero, while the potential reward is a 100% refund on an item they already possess in perfect condition.</p><p dir="ltr">It's <strong>a low-risk, high-reward scenario that incentivizes fraudulent behavior</strong>.</p><p dir="ltr">Ultimately, these AI tools give the masses the power to create a convincing reality that aligns with their claim, turning a merchant's own evidence-based refund policy into a weapon against them.<br /></p></div><div id="article-section-text-273771" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/genAI-refund-abuse-table.png" data-image="273758" alt="A coffee table manipulated by AI to look broken." class="c2" /><figcaption><strong><em>A coffee table manipulated by AI to look broken.</em></strong></figcaption></figure></div><div id="article-section-text-273791" class="article_content__text"><h2 dir="ltr">Types of AI-powered refund abuse</h2><p dir="ltr">To better be able to detect and block them, it is useful to categorize these types of threats, based on the abuser’s target, methods and motive.</p><h3 dir="ltr">Category 1: Low-value "inconvenience" fraud</h3><p dir="ltr">This targets low-cost items where the merchant is unlikely to set up return shipping. The goal is to get a free product by making a return financially illogical for the business.</p><p dir="ltr">If successful, it means the consumer has their cake and eats it too, both receiving their money back and keeping a perfectly good product.</p><p dir="ltr"><strong>Example scenario:</strong> A customer buys a $15 t-shirt. They receive the correct item but use an AI tool to generate a photo of it in the wrong size or wrong color. They expect the merchant won't pay £5 for a return label on a £15 item and will likely just issue a refund.</p><h3 dir="ltr">Category 2: Prohibitive return fraud</h3><p dir="ltr">This type of scheme targets expensive, bulky or impossible to return items where return logistics are a nightmare. The fraudster creates "evidence" of such catastrophic damage that the merchant writes the item off.</p><p dir="ltr">The hope here is that the merchant will take the picture at face value. In some cases, the type of issue claimed might make it especially difficult to return the item – for example, broken glass or especially bulky items.</p><p dir="ltr"><strong>Example scenario:</strong> A customer orders a large mirror costing $400. The mirror arrives in perfect condition. They use AI to generate an image that makes the mirror look smashed. The logistics of finding a specialist carrier to collect broken glass is uneconomical for the courier. The fraudster also cites safety concerns about handling the broken mirror and therefore makes it clear they will be disposing of it and not handling it.</p><p dir="ltr">Refusing this refund would inevitably lead to an unwinnable chargeback. And it’s more common than one would expect. For instance, battery-containing electronics require specialist couriers, whose services are more expensive.<br /></p></div><section id="article-section-redesignedCtaSection-273833" class="redesigned-section section-landing-subscribe redesigned-cta-section redesigned-subscribe redesigned-subscribe--"><div id="article-section-text-273893" class="article_content__text"><h3 dir="ltr">Category 3: Perishables no-return abuse</h3><p dir="ltr">This very common scheme targets <a href="https://pages.ravelin.com/food-delivery-fraud-ebook" rel="noopener" target="_blank">food and grocery delivery</a>, where returns are impossible both because of the type of goods delivered, which cannot be resold, and because of a lack of returns infrastructure.</p><p dir="ltr">These merchants already face rife missing item fraud and quality issues; they now have to also manage AI generated refund claims.</p><p dir="ltr">Evidence in this category is easy to fake and impossible to verify, creating a headache for food delivery <a href="https://www.ravelin.com/blog/online-marketplace-fraud-trends">marketplaces</a>.</p><p dir="ltr"><strong>Example scenario:</strong> A customer orders a pizza. The customer takes a photo of the pizza immediately and uses an AI model to make the pizza look burned<strong>.</strong> Since the restaurant can't inspect the item, they're often forced to issue a refund to avoid a bad review or a <a href="https://www.ravelin.com/blog/chargeback-vs-refund-abuse">dispute</a>.</p></div><div id="article-section-text-273792" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/ai-powered-refund-abuse-and-friendly-fraud-pizza.webp" data-image="273757" alt="A picture of a pizza, edited by GenAI to look burned." /><figcaption><strong><em>This pizza was edited by GenAI to look burned within seconds.</em></strong></figcaption></figure></div><div id="article-section-text-273793" class="article_content__text"><h3 dir="ltr">Category 4: Used-then-damaged wardrobing</h3><p dir="ltr">This category of AI-assisted refund abuse is an evolution of wardrobing – the practice of ordering something intending to wear it once and then return it – and targets <a href="https://www.ravelin.com/blog/fashion-retail-industry-pulse-challenges-fraud-risks">fashion retailers</a>, mainly.</p><p dir="ltr">GenAI can flip wardrobing on its head:</p><ol><li dir="ltr">
<p dir="ltr">The refund abuser takes a photo of the item as soon as they receive it.</p>
</li>
<li dir="ltr">
<p dir="ltr">They use AI to add fake evidence of damage to the product, which still has all its tags intact and is fresh out of the box.</p>
</li>
<li dir="ltr">
<p dir="ltr">They file a request for a refund due to damaged goods.</p>
</li>
</ol><p dir="ltr">Once the retailer accepts and requests for the item to be returned, the customer has carte blanche to wear it until the end of their return window.</p><p dir="ltr">They will then damage the product before returning it – roughly in the way depicted by the AI.</p><p dir="ltr">This doesn’t need to be perfect: They can send the item back knowing they submitted photographic “proof” of damage from the day of receipt, with all the tags still attached.</p><p><strong>Example scenario:</strong> A consumer buys a $840 dress for a wedding. They take a photo and use AI to add a large tear on the back of the dress. They claim it arrived this way, knowing a severely damaged item can't be resold. If the merchant wants the item back, the abuser can put the hole in it – otherwise, they keep the dress and get their money back.</p></div><div id="article-section-text-273794" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/ai-powered-refund-abuse-tshirt.png" data-image="273750" alt="Example AI prompt that can generate fake refund claim pictures." class="c2" /><figcaption><strong><em>Example AI prompt that can generate fake refund claim pictures.</em></strong></figcaption></figure></div><div id="article-section-text-273795" class="article_content__text"><h3 dir="ltr">Category 5: Service evidence manipulation</h3><p dir="ltr">This type of fraud applies to rentals and services where the state of an item or space at different times is key. For example, this could be car rentals or accommodation bookings.</p><p dir="ltr">On a simple level, a consumer may use AI to hide damage they have caused, thus avoiding paying penalties and remediation fees.</p><p dir="ltr">Because GenAI models can generate a series of pictures with consistency, those who wish to defraud companies can even set up consecutive pictures with different amounts of damage, being able to create a complete, fraudulent timeline.</p><p dir="ltr">In the <a href="https://www.ravelin.com/blog/travel-ticketing-fraud-trends-2025">accommodation/travel sector</a>, GenAI makes it easy to write inaccurate complaints with generated evidence showing bug infestations, stains on bed sheets and other issues to receive refunds on hotel or accommodation stays once a customer has checked out.</p><p><strong>Example scenario:</strong> A customer rents a car and causes a scratch or damage during their rental period. At the end of the rental, they choose to do a contact-free drop off. This requires photos taken of the car at a designated location. The customer uses an AI tool to edit their "after" photos and remove the damage. If the damage is later identified, the consumer argues that there was no damage when they returned the car, and they present the generated image(s) as evidence.</p></div><div id="article-section-text-273796" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/ai-powered-refund-abuse-dirty-tshirt.webp" data-image="273760" alt="A t-shirt edited by AI to look dirty" /><figcaption><strong><em>GenAI damage comes in many forms: A new t-shirt edited by AI to look stained.</em></strong></figcaption></figure></div><div id="article-section-text-273799" class="article_content__text"><h2>A robust framework to block GenAI refund claims</h2><p>Unfortunately, the sky is the limit when it comes to AI-enabled refund abuse and dispute fraud.</p><p>Both opportunist consumers and professional criminals are continuing to devise new ways to defraud companies, including with GenAI for refund claims and chargeback requests.</p><p>Combating this urgent threat requires <strong>a dynamic, technology-driven framework designed to introduce hurdles</strong> that are trivial for honest customers but significantly difficult for fraudsters.</p><p>The framework combines different types of defences, all working together to solve the issue:</p><h3>Level 1: Passive and automated defenses</h3><p>Working in the background, tech solutions analyze the customer as well as the submitted evidence, without adding friction.</p><ul><li dir="ltr">
<p><strong>EXIF and metadata analysis:</strong> This is a simple first check. An image file lacking any metadata, or with metadata showing it was passed through known editing software, can be automatically flagged for <a href="https://www.ravelin.com/blog/5-ways-to-turbocharge-your-manual-reviews">manual review</a> or the claim flagged for deeper checks.</p>
</li>
<li dir="ltr">
<p><strong>Refund abuse fraud solutions:</strong> <a href="https://www.ravelin.com/solutions/refund-abuse">AI-powered refund abuse detection</a> makes use of all the information about a customer and transaction, including their historic data, to estimate the level of risk involved with a refund claim.</p>
</li>
<li dir="ltr">
<p><strong>Device and image fingerprinting:</strong> This can flag mismatched data. Every camera produces images with a distinct digital fingerprint – a specific resolution, aspect ratio, compression type, and color profile. AI models also have their own fingerprints, often outputting images at a standard resolution (e.g., 1024x1024 pixels). If a customer submits a photo supposedly from a high-end smartphone but its technical properties match a known AI model's output, it can be flagged as suspicious.</p>
</li>
<li dir="ltr">
<p><strong>Emerging flagging technologies:</strong> Tools such as Google's <a href="https://deepmind.google/models/synthid/" rel="noopener" target="_blank">SynthID</a> are designed to watermark AI-generated content in a way that is invisible to the human eye but detectable by an algorithm. As these technologies emerge, there will be opportunities to integrate these tools into your stack to provide a powerful automated filter.</p>
</li>
<li dir="ltr">
<p><strong>Link analysis using graph networks</strong>: A large portion of the refund abuse affecting merchants comes from a very small group of repeat fraudsters. <a href="https://www.ravelin.com/insights/link-analysis-and-graph-database-for-fraud-detection">Graph network link analysis</a> is a great way to easily identify hidden connections between customers. For example, abusive customers who create multiple accounts to hide the true number of refunds they’ve claimed.</p>
</li>
</ul></div><div id="article-section-text-273798" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/edited-with-AI-metadata.png" data-image="273751" alt="refund claim image edited by AI" class="c2" /></figure></div><div id="article-section-text-273868" class="article_content__text"><h3>Level 2: Low-friction verification requests</h3><p>When focusing on the image of the claim, or when your fraud stack has flagged a request as otherwise suspicious, there are a number of steps you can take as part of your refund claim verification:</p><ul><li dir="ltr">
<p><strong>Request multiple photos/angles:</strong> It's exponentially more difficult to create three or four images from different angles that are all consistent in their fake damage or scenario. You might, for example, want to try asking for a close-up of the damage, one from a few feet away, and one of the entire item.</p>
</li>
<li dir="ltr">
<p><strong>Request video evidence:</strong> A short, 10-second video panning around the item is much harder to fake than a static image – although not impossible.</p>
</li>
</ul><p>However, this can’t be the cornerstone of your approach – not for long. The generative AI tools are getting better and better; chances are the above will no longer work fairly soon.</p><h3>Level 3: High-friction and definitive verification</h3><p>When investigating the claim of a high-risk customer (whom you still don’t want to block) or if the item is of high value, consider the following:</p><ul><li dir="ltr">
<p><strong>In-app camera submission:</strong> For merchants with a mobile app, this is a game-changer. This policy requires that all evidence for a return must be captured live, using the camera function within the merchant's app. This bypasses the user's camera roll entirely, preventing them from uploading an edited image. The consumer arguably experiences even less friction this way, as they don’t have to leave the app.</p>
</li>
<li dir="ltr">
<p><strong>Live video assistant calls:</strong> For a major claim, a customer support agent can initiate a brief video call. A consumer who has faked damage to their item will be unable to comply and will often abandon the claim.</p>
</li>
<li dir="ltr">
<p><strong>Strategic forced returns:</strong> Even when it's not financially worth it, insisting on a return can be a powerful deterrent. A fraudster often just wants a free item, not the hassle of packaging and shipping it back, and may again choose to drop their claim.</p>
</li>
<li dir="ltr">
<p><strong>Leverage in-store returns:</strong> Mandating a "Buy Online, Return In Store" (BORIS) policy for flagged refund claims (or simply for all refunds) moves the fraud attempt from the anonymous digital world into the real world, thus limiting the likelihood the fraudster continues to push for a refund.</p>
</li>
</ul></div><div id="article-section-text-273769" class="article_content__text"><figure><img src="https://storage.googleapis.com/ravelin-website-assets-production/assets/images/ai-powered-refund-abuse-for-food-delivery.jpeg" data-image="273752" alt="AI powered refund abuse for food delivery" /><figcaption><strong><em>A screenshot from a much-discussed recent social media post.</em></strong></figcaption></figure></div><div id="article-section-text-273817" class="article_content__text"><h2>The cornerstone of your approach: Assess the customer, not just the claim</h2><p dir="ltr">Perhaps the most critical strategic shift you can make to protect against the onslaught of GenAI-generated fake evidence is <strong>to move from a reactive, claim-by-claim validation process to a proactive,</strong> <strong>customer-centric risk assessment model.</strong></p><p dir="ltr">The advanced verification techniques listed above can be powerful, but they can also introduce friction for your honest, loyal customers. Subjecting a VIP customer to a high-friction video call over a $30 damaged item is a good way to lose their business forever.</p><p dir="ltr">The solution is to <strong>apply friction dynamically, based on risk</strong>. Your <a href="https://www.ravelin.com/solutions/refund-abuse">refund abuse detection and prevention system</a> should be built to trust your best customers implicitly while rigorously verifying the suspicious ones.</p><p dir="ltr">This is where Ravelin excels. Because we look at customers holistically, taking into account their lifetime history, we provide a true estimate of the amount of trust a customer should inspire.</p><p dir="ltr">No matter whether they request a lot of refunds or just a few, the entirety of their activity, device, location and other data will inform the recommendation – not just a single transaction.</p><p dir="ltr">Following this logic, instead of asking "Is this photo of a broken mirror real?", the primary question should be <strong>"What is the likelihood this specific customer is attempting abuse?"</strong></p><p dir="ltr">This is answered by building a holistic risk score based on data you already have:</p><ul><li dir="ltr">
<p dir="ltr"><strong>Transaction history:</strong> What is the customer's return and refund request rate compared to the average? What is their purchase frequency and average order value?</p>
</li>
<li dir="ltr">
<p dir="ltr"><strong>Account history and behavior:</strong> Is this a brand-new account with a large first order? How quickly after delivery did they file a claim? What is the customer’s lifetime value (LTV)?</p>
</li>
<li dir="ltr">
<p dir="ltr"><strong>Reputational data:</strong> Does the email address use a reputable domain or a disposable email service?</p>
</li>
<li dir="ltr">
<p dir="ltr"><strong>Demographics and item data:</strong> What is the level of risk posed by this type of device? Location? Is the item one that has historically invited a lot of fraud for the merchant? What is its value?</p>
</li>
<li dir="ltr">
<p dir="ltr"><a href="https://www.ravelin.com/blog/nuanced-consortium-data-at-ravelin"><strong>Consortium data</strong></a><strong>:</strong> Is the data associated with this customer high-risk across your fraud vendor’s network of merchants? And is this information objective (e.g. identified fraud) or subjective (manual reviews that were not verified)?</p>
</li>
</ul><h3 dir="ltr">Segmenting customers to inspire loyalty</h3><p dir="ltr">By combining factors like these, you can segment customers into tiers. For example, you can have trusted, standard, high-risk and/or VIP customers.</p><p dir="ltr">How you approach each is up to your fraud tolerance and customer retention goals – but here is one example:</p><ul><li dir="ltr">
<p dir="ltr"><strong>Trusted and VIP customers</strong> might get instant, no-questions-asked refunds because the lifetime value of keeping them happy far outweighs the minimal risk (after ensuring there is no likelihood of <a href="https://www.ravelin.com/insights/account-takeover-fraud">account takeover</a>, of course).</p>
</li>
<li dir="ltr">
<p dir="ltr"><strong>Standard customers</strong> might go through the low-friction level 2 verification processes as outlined above – or have other types of checks and balances introduced.</p>
</li>
<li dir="ltr">
<p dir="ltr"><strong>High-risk customers</strong> would automatically be funnelled into the high-friction level 3 pathways, where they have to spend time proving the legitimacy of their claim, if it is indeed legitimate.</p>
</li>
</ul><p dir="ltr">Such <strong>a dynamic, intelligent and risk-based approach</strong> will ensure that your fraud and abuse detection measures are a targeted shield that protects your business, not a blunt instrument that alienates your best customers.<br /></p></div><section id="article-section-redesignedCtaSection-273819" class="redesigned-section section-landing-subscribe redesigned-cta-section redesigned-subscribe redesigned-subscribe--"><div id="article-section-text-273818" class="article_content__text"><h2>Related resources</h2></div></section></section></div><div><h2 class="text-left border-top-1-grey pt-6 pt-lg-8 mb-2 mb-lg-3">Author</h2><div class="row col-12 col-lg-6 mb-4 blog-entry--author d-flex align-items-start"><div class="bg-white p-3 flex-grow-1 rounded-3"><p class="mb-2 text-lg">Jamie George VP Account Management and Partnerships</p><p>Coming from an economics background, Jamie George has been with Ravelin for over eight years. Earning his stripes in Sales initially, he…</p><p class="mb-0 text-lg mt-1"><a class="text-primary font-weight-semibold" href="https://www.ravelin.com/author/jamie-george">More from this author</a></p></div></div></div><div class="blog-share mt-4 flex flex-column"><p class="text-xs faded-blue mr-3">Share this article:</p></div></div></div></section><section class="section section-resources pt-0"><div class="container pb-6"><h2 class="text-center border-top-1-grey pt-6 pt-lg-8 mb-2 mb-lg-3">Related content</h2></div></section>]]></description>
      <link>https://www.ravelin.com/blog/ai-powered-refund-abuse-dispute-fraud</link>
      <guid>https://www.ravelin.com/blog/ai-powered-refund-abuse-dispute-fraud</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The DoD spent billions on fruit baskets, pianos, and crab]]></title>
      <description><![CDATA[<div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>The Pentagon spent more money in September—the end of the 2025 fiscal year—than it had in any other year since 2008. But a good chunk of the budget wasn’t used for anything that could be considered a pertinent military expense.</p>
<p>The Defense Department burned through $93 billion that month alone, signing checks left and right in order to dry up its congressionally allocated budget, according to a recent analysis by the government watchdog <a href="https://openthebooks.substack.com/p/pentagon-should-focus-on-defense" target="_blank" rel="nofollow">Open the Books</a>.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>There is pressure to spend: If federal agencies don’t use the entirety of their budgets by the end of the fiscal year, then they lose access to that cash forever, potentially putting themselves in a situation where they have to request a reduced budget the following year. But the Pentagon’s long list of luxuries is hardly defensible.</p>
<p>Some of the frivolous September purchases made under Secretary Pete Hegseth’s stewardship include a $98,329 Steinway &amp; Sons grand piano for the Air Force chief of staff’s home, $5.3 million for Apple devices such as the new iPad, and an astronomical amount of shellfish, including $2 million for Alaskan king crab and $6.9 million worth of lobster tail. (Lobster tail is apparently a favorite of Hegseth’s Pentagon—the department spent more than $7.4 million total on the luxury item in March, May, June, and October.)</p>
<p>In other pricey food purchases, the government decided to drop $15.1 million for ribeye steak (again, just in September), $124,000 for ice cream machines, and $139,224 on 272 orders of doughnuts.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Weeks later, millions of Americans would lose their SNAP benefits amid the longest government shutdown in U.S. history. More still stand to lose eligibility to the food assistance program thanks to a Republican crusade that added stricter work requirements to the program, piling on paperwork and documentation mandates.</p>
<p>One of the largest bulk expenditures was just for furniture, for which the Pentagon decided to shell out $225 million. That included $12,000 for fruit basket stands, and checks totaling more than $60,000 for Herman Miller recliners. All in all, the agency spent more on furniture in 2025 than it had in over a decade.</p>
<p>In the last five days of September alone, the department blew through $50.1 billion on just grants and contracts. For context, only nine other countries spend that much on the entirety of their defense budget per year. It’s also more than the total military budgets of Canada and Mexico combined.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>The federal government had a $1.8 trillion deficit in 2025. Ultimately, the military’s massive expenditures offered up more evidence that the Trump administration has not put any meaningful effort into cracking down on needless government spending, a pledge that Donald Trump has wielded on the campaign trail since 2015.</p>
<p>“Under Secretary Hegseth, the Pentagon has consistently said its mission is to refocus on warfighting and lethality,” Open the Books CEO John Hart said. “Last year, we highlighted the problem of wasteful use-it-or-lose-it year-end spending. We noted that this reform is fully within the secretary’s control and is a historic opportunity to make good on that promise.”</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>Do Steve Witkoff and Jared Kushner actually understand nuclear energy enough to describe Iran’s capabilities to Donald Trump, let alone negotiate a nonproliferation agreement with Tehran?</p>
<p>Several nuclear experts have raised questions about the disastrous duo’s technical understanding of uranium enrichment after they presented an assessment of Iran’s Research Reactor that made no sense, <a href="https://www.ms.now/news/trump-iran-nuclear-reactor-war-evidence" target="_blank" rel="nofollow">MS NOW</a> reported Monday.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>For the uninitiated, here’s a crash course in nuclear energy: Most nuclear reactors that produce electricity only require uranium that is enriched to between 3 percent and 5 percent. Highly enriched uranium is anything above 20 percent, and weapons-grade uranium is enriched above 90 percent, according to the <a href="https://armscontrolcenter.org/uranium-enrichment-for-peace-or-for-weapons/" target="_blank" rel="nofollow">Center for Arms Control and Non-Proliferation</a>.</p>
<p>Tehran’s Research Reactor is a 60-year old facility designed to use less than 20 percent enriched uranium, not intended for use outside of research and producing medicine. The Trump administration has claimed, without providing any evidence, that the facility was being used to covertly stockpile uranium that would become weapons-grade. Nuclear experts aren’t buying it.</p>
<p>“An [active] operating reactor cannot be used as storage. I am not aware of this ever having happened,” Claus Montonen, a retired nuclear physicist and board member of the International Network of Engineers and Scientists for Global Responsibility, told MS NOW.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Elena Sokova, the executive director of the Vienna Center for Disarmament and Non-Proliferation, told MS NOW that the administration’s “confusing and misleading” assessment of the reactor was laden with “technical errors.”</p>
<p>“It mixes up different elements of the nuclear program and their potential proliferation capabilities,” Sokova said. “Research reactors are not capable of doing enrichment of uranium, whether for civil or military purposes.”</p>
<p>Witkoff and Kushner chose not to have nuclear technical experts present during negotiations in Geneva, a senior Middle East diplomat with knowledge of the talks told <a href="https://www.ms.now/news/trump-iran-nuclear-reactor-war-evidence" target="_blank" rel="nofollow">MS NOW</a>. The United States then chose to skip out on technical talks scheduled for last Monday in Vienna.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Last week, Witkoff offered this defense of his credentials: “I wouldn’t tell you I’m an expert in nuclear, but I’ve learned quite a bit, and I’ve studied it and have read quite a bit about it, and I’m competent to sit at the table and discuss it, and Jared [Kushner] is as well.”</p>
<p>Ahead of Trump’s military campaign in the Middle East, Witkoff <a href="https://www.cbsnews.com/news/trump-steve-witkoff-iran-enriched-uranium-11-nuclear-bombs/" target="_blank" rel="nofollow">claimed</a> that Iran had amassed 460 kilograms of uranium at 60 percent enrichment, enough to potentially make 11 bombs within a few weeks. <em>The Wall Street Journal</em> reported Iran had enough uranium to make 12.</p>
<p>However, during negotiations, Iranians offered to turn over that uranium, the Middle East diplomat told MS NOW. The Iranians told Witkoff and Kushner that they’d only started enriching uranium after Trump <a href="https://www.npr.org/2018/05/08/609383603/trump-u-s-will-withdraw-from-iran-nuclear-deal" target="_blank" rel="nofollow">withdrew</a> from the Iran nuclear deal in 2018.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>A senior Trump official had confirmed that Iranians “talked about turning over material to us.” But talks ended abruptly when the United States launched a joint attack with Israel.</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>A federal judge has rejected President Trump’s new appointees to the New Jersey U.S. Attorney’s Office, ruling that the president is illegally trying to get around Senate confirmation.</p>
<p>Chief U.S. District Judge Matthew Brann <a href="https://storage.courtlistener.com/recap/gov.uscourts.njd.540663/gov.uscourts.njd.540663.317.0_2.pdf" target="_blank" rel="nofollow">ruled</a> Monday that the three-prosecutor team running the office is leading “unlawfully,” as the Trump administration tries to cite “enormous grants of executive power hidden in the vagaries and silences of the code.”</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>“Why does the fate of thousands of criminal prosecutions in this district potentially rest on the legitimacy of an unprecedented and byzantine leadership structure?” Brann wrote in his ruling. “The government tells us: The president doesn’t like that he cannot simply appoint whomever he wants.”</p>
<p>Several criminal cases in the district could be thrown out, with “scores of dangerous criminals” possibly able to escape punishment, Brann wrote, because the Trump administration doesn’t want to appoint U.S. attorneys legally—not just in New Jersey, but all around the country.</p>
<p>“The Office of the United States Attorney for at least five other Districts is currently vacant and in each case it appears that the Government is running the office through a delegation of authority to an individual of the Attorney General and President’s unilateral choice,” Brann wrote, noting that in two cases, judges used their legal power to appoint an attorney to fill the vacancy, and Trump fired their picks too.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>“In both cases the President fired their selection within hours and [Deputy Attorney General Todd Blanche] made combative (and legally incomplete) posts clearly indicating that the Department of Justice would not permit anyone to hold any United States Attorney’s office if that person was not handpicked by the President,” Brann continued.</p>
<p>The whole reason that the New Jersey office was being run by three attorneys was because Trump’s appointment of his personal lawyer, Alina Habba, as U.S. attorney was <a href="https://newrepublic.com/post/203771/appeals-court-trump-alina-habba-out-of-job" target="_blank" rel="nofollow">found</a> to be illegal. Habba, who was set to lose her nomination vote in the Senate, unlawfully stayed past her interim term. She now works for the Justice Department in Washington, D.C., and called Monday’s ruling “ridiculous” <a href="https://x.com/AlinaHabba/status/2031085185983197357" target="_blank" rel="nofollow">on X</a>.</p>
<p>“Judges may continue to try and stop President Trump from carrying out what the American people voted for, but we will not be deterred,” Habba wrote. “The unconstitutionality of this complete overreach into the Executive Branch, time and time again, will not succeed. They would rather have no U.S. Attorney than safety for the people of NJ.”</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Ridiculous or not, absent the Senate, Trump’s handpicked prosecutors are going to keep getting rejected by federal judges. Unless the president starts appointing them legally, every federal prosecution is going to be in jeopardy.</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>The Iranian Assembly of Experts named Mojtaba Khamenei the country’s new supreme leader just a week after the U.S. and Israel assassinated his father, <a href="https://www.aljazeera.com/news/2026/2/28/irans-supreme-leader-ali-khamenei-killed-in-us-israeli-attacks-reports" target="_blank" rel="nofollow">Ayatollah Ali Khamenei</a>, along with other senior officials. Now President Trump wants to kill him too—unless he capitulates to his demands.</p>
<p>“President Trump has told aides he would back the killing of new Iranian Supreme Leader Mojtaba Khamenei if he proves unwilling to cede to U.S. demands, such as ending Iran’s nuclear development,” <a href="https://www.wsj.com/livecoverage/iran-war-us-israel-trump-2026/card/trump-open-to-khamenei-being-killed-if-he-doesn-t-cede-to-u-s-demands-hl9KqawqqO2pCCWODSej" target="_blank" rel="nofollow"><em>The Wall Street Journal</em></a> reported on Monday, citing current and former U.S. officials.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>“The U.S. has now established an operational doctrine of assassinating a foreign head of state with no congressional declaration and threatening to kill his successor if the successor doesn’t comply with U.S. policy demands,” Christine Villaverde, chair of the advocacy group Anchoring Democracy, <a href="https://x.com/Villaverde4NC/status/2031078089061491175" target="_blank" rel="nofollow">wrote on social media</a>.</p>
<p>“‘We’re just gonna keep assassinating a country’s leadership until they appoint someone we like’ is a really novel precedent in international relations and statecraft which I hope the geniuses running the show in DC and Israel fully understand the implications of,” national security analyst John Schindler <a href="https://x.com/20committee/status/2031083177448473079" target="_blank" rel="nofollow">wrote on X</a>.</p>
<p>Trump has called the younger Khamenei “<a href="https://nypost.com/2026/03/08/world-news/irans-next-supreme-leader-is-not-going-to-last-long-without-us-approval-trump-warns/" target="_blank" rel="nofollow">unacceptable</a>” and “<a href="https://www.nbcnews.com/politics/donald-trump/trump-seizing-iran-oil-rcna262437" target="_blank" rel="nofollow">a big mistake</a>.” But killing leader after leader until one decides to bend the knee is far from a plan at all.</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>The Department of Homeland Security is trying to hide hundreds of ICE-mobiles they can’t actually use to detain immigrants.</p>
<p>ICE’s former deputy director, Madison Sheahan, wasted millions of taxpayer dollars on 2,500 vehicles custom-wrapped to say “ICE” on the side, three sources told the <a href="https://www.washingtonexaminer.com/policy/immigration/4478925/deputy-director-ice-bought-thousands-marked-vehicles-cannot-use/" target="_blank" rel="nofollow"><em>Washington Examiner</em></a>. The gaudy cars feature massive ICE logos, red stripes, and a golden decal of President Donald Trump’s name on the back window.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>The vehicles first appeared in a <a href="https://newrepublic.com/post/199171/donald-trump-ice-trucks-music-video-tax-dollars" target="_blank" rel="nofollow">DHS video intended to make ICE look cool</a>. But a fleet of ostentatious cars are useless to Trump’s masked militia, which typically <a href="https://newrepublic.com/post/207479/ice-kidnaps-journalist-nashville" target="_blank" rel="nofollow">disappears people</a> using unmarked vehicles.</p>
<p>“It’s ridiculous because you don’t want to advertise what you’re doing,” one person told the <em>Examiner</em>. “We’re just hiding them in a parking garage somewhere because we don’t want to drive them. Who wants to drive the marked vehicles?”</p>
<p>A second person familiar with the matter said the marked cars are being used for custodial pickups and transfers. That’s really all they’re good for.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>It seems that the 28-year-old Kristi Noem handpicked to oversee ICE’s billion-dollar budget may have wasted millions of dollars. DHS <a href="https://www.wcnc.com/article/news/investigations/hendrick-motorsports-contract-ice-immigration-enforcement/275-0c323ad9-4855-44b0-96b7-a9616a9feaf9" target="_blank" rel="nofollow">spent</a> $1.5 million on 25 new sports utility vehicles in November, and later paid an additional $174,000 to $230,000 to get them delivered. Sheahan went so far as to request an upgrade for most of the agency’s fleet from unmarked cars to the flashy new ones. Perhaps she had imagined that ICE would act as a kind of police, and not the president’s untrained extrajudicial paramilitary.</p>
<p>Sheahan left her role last month to pursue a congressional campaign. Since her departure, DHS has been scrambling to receive the rest of the vehicles unwrapped. Sheahan’s apparent mentor Noem was <a href="https://newrepublic.com/post/207407/kristi-noem-zero-clue-donald-trump-fired" target="_blank" rel="nofollow">unceremoniously fired</a> last week.</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>The White House is working to dredge up another election conspiracy with eight months on the clock until midterms.</p>
<p>The Trump administration subpoenaed records related to the 2020 presidential election Monday from Maricopa County, Arizona.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Arizona Senate President Warren Peterson wrote on X that he had complied with a federal grand jury subpoena to turn over records of the county audit to federal authorities.</p>
<p>“The FBI has the records. Any other report is fake news,” Peterson <a href="https://x.com/votewarren/status/2031046018192781455" target="_blank" rel="nofollow">wrote</a>, responding to a post in which Donald Trump said the development was “great!” Peterson is currently running to be Arizona’s attorney general, though his candidacy is <a href="https://pro.stateaffairs.com/az/yellow-sheet/politics/warren-petersen-attorney-general-2" target="_blank" rel="nofollow">reportedly in doubt due</a> to the state’s “zombie laws,” which require candidates to have recently practiced law before they announce their candidacy.</p>
<p>Officials in Maricopa County, however, had no idea what Peterson was talking about.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Jason Berry, a spokesperson for the Maricopa County Board of Supervisors, told the Phoenix-area radio station KJZZ that the board had not received a subpoena.</p>
<p>“Maricopa County runs elections in accordance with the law. We have not received a subpoena at this time but will cooperate if that were to occur,” Berry <a href="https://www.kjzz.org/npr-top-stories/2026-03-09/top-arizona-lawmaker-says-hes-complied-with-a-subpoena-for-2020-election-records" target="_blank" rel="nofollow">said</a>.</p>
<p>The Maricopa County recorder’s office also said it had not received a subpoena, referring questions back to Peterson.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>It’s the second state at which the administration has recently taken aim as it continues to sow doubt over Donald Trump’s major political loss. In December, Attorney General Pam Bondi <a href="https://www.justice.gov/crt/media/1420721/dl" target="_blank" rel="nofollow">sued</a> Fulton County officials in Georgia, demanding that they turn over “all used and void ballots, stubs of all ballots, signature envelopes, and corresponding envelope digital files.”</p>
<p>Weeks later, the FBI raided an elections office outside of Atlanta.</p>
<p>The Georgia suit was filed the same day as the DOJ announced legal action against <a href="https://www.justice.gov/opa/pr/justice-department-sues-four-additional-states-and-one-locality-failure-comply-federal" target="_blank" rel="nofollow">four more states</a>—Colorado, Hawaii, Massachusetts, and Nevada—in a sweeping national effort to access sensitive voter data.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Since Trump first planted the seeds of doubt about the results of the 2020 election, a litany of his allies have continued to tend and water the theory—so much so that within a handful of years, refusing to admit that Trump ever lost to Joe Biden has become a fealty test for MAGA membership.</p>
<p>Both Maricopa County and Fulton County have played major roles in Trump’s political conspiracy. But there is no doubt: Trump lost that election by a landslide, coming up short by 38 electoral votes. More evidence that Trump did not win includes the fact that he was not inaugurated in 2021, and did not serve a day as president until he was reelected in 2024.</p>
<p>But for anyone still in doubt, know that the theory has been thoroughly debunked by the president’s own appointees. Trump’s last attorney general, Bill Barr, <a href="https://apnews.com/article/barr-no-widespread-election-fraud-b1f1488796c9a98c4b1a9061a6c7f49d" target="_blank" rel="nofollow">announced</a> in 2022 that despite an intensive, multi-agency investigation, no evidence of widespread fraud had been discovered that supported the president’s wild claims.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Yet the theory—and Trump’s vast cadre of yes men—persist. Late last year, Trump granted “full, complete, and unconditional” pardons for dozens of the alleged co-conspirators that helped fuel the scheme, including disgraced New York Mayor Rudy Giuliani, Sidney Powell, Boris Epshteyn, John Eastman, Mark Meadows, and 72 others.</p>
<p><em>This story has been updated.</em></p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>Donald Trump has fired a Republican member of the National Transportation Safety Board, or NTSB, accusing him of misconduct on the job.</p>
<p>J. Todd Inman was fired late last week and said he was given no explanation why. On Monday, the White House <a href="https://www.washingtonpost.com/politics/2026/03/09/ntsb-inman-fired/" target="_blank" rel="nofollow">released</a> a statement accusing him of “inappropriate alcohol use on the job, harassment of staff, misuse of government resources, and failure to attend at least half of NTSB meetings,” saying he was “lawfully removed” due to “highly concerning reports.”</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>“The Trump administration remains committed to maintaining safety and security for Americans in the air and on the ground,” White House spokesperson Kush Desai said in a statement.</p>
<p>Inman, meanwhile, told <em>The Washington Post</em> that it was all made up.</p>
<p>“I categorically deny the false allegations made in the White House statement,” Inman said. “It has become increasingly obvious this action was a political hit job. While not my original intent I look forward to defending my reputation against those responsible with every legal means possible.”</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Inman didn’t tell the <em>Post</em> why he said his firing was political, but he had represented the NTSB at news conferences since an American Airlines flight <a href="https://newrepublic.com/article/190980/transcript-trump-seethes-journos-expose-plane-crash-drivel" target="_blank" rel="nofollow">crashed</a> in Washington, D.C., at the beginning of Trump’s second term.</p>
<p>Last May, Trump fired another member of the NTSB, vice chair Alvin Brown, who was <a href="https://www.cbsnews.com/news/trump-white-house-fires-alvin-brown-ntsb/" target="_blank" rel="nofollow">appointed</a> by President Biden. Brown is <a href="https://www.jacksonville.com/story/news/politics/2025/12/04/alvin-brown-adds-race-discrimination-to-lawsuit-against-trump/87611010007/" target="_blank" rel="nofollow">suing</a> the Trump administration over his ouster, arguing that Trump didn’t have the authority to fire him, even as the Senate <a href="https://www.nytimes.com/2026/02/25/us/politics/senate-vote-air-safety-official.html" target="_blank" rel="nofollow">confirmed</a> his replacement, John DeLeeuw, last month. The Supreme Court is expected to rule in favor of the Trump administration. Will Inman sue as well?</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>One of the same law firms that President Trump <a href="https://newrepublic.com/post/195786/judge-26-exclamation-points-donald-trump-executive-order" target="_blank" rel="nofollow">tried and failed</a> to suppress is now representing AI company Anthropic in its lawsuit against the Trump administration.</p>
<p>Last year, Trump signed an executive order <a href="https://www.whitehouse.gov/presidential-actions/2025/03/addressing-risks-from-wilmerhale/" target="_blank" rel="nofollow">demanding</a> that government agencies eliminate WilmerHale’s government contracts, their security clearances, and their access federal buildings, on the grounds that they allegedly “rewarded” Robert Mueller by allowing him to remain on their payroll after his investigation into Trump’s connections to Russian interference in the 2016 presidential election. The executive order was ruled unconstitutional in May.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Now, that same law firm is helping Anthropic sue the Trump administration for labeling them a “supply risk” after the AI company <a href="https://newrepublic.com/post/207133/hegseth-anthropic-refuses-bend-pentagon" target="_blank" rel="nofollow">refused to lift regulations</a> restricting government access to surveillance and unmanned weapons systems.</p>
<p>More than a dozen federal agencies are targeted in the lawsuit, including the Departments of Defense, Treasury, State, and Veterans Affairs.</p>
<p>“Anthropic was founded based on the belief that AI technologies should be developed and used in a way that maximizes positive outcomes for humanity, and its primary animating principle is that the most capable artificial-intelligence systems should also be the safest and the most responsible. Anthropic brings this suit because the federal government has retaliated against it for expressing that principle,” the <a href="https://storage.courtlistener.com/recap/gov.uscourts.cand.465515/gov.uscourts.cand.465515.1.0.pdf" target="_blank" rel="nofollow">lawsuit reads</a>.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>The lawsuit goes on to cite Trump and Defense Secretary Pete Hegesth’s statements on Anthropic against them. “When Anthropic held fast to its judgment that Claude cannot safely or reliably be used for autonomous lethal warfare and mass surveillance of Americans, the President directed every federal agency to ‘IMMEDIATELY CEASE all use of Anthropic’s technology’—even though the Department of War (Department) had previously agreed to those same conditions,” the suit states. “Hours later, the Secretary of War directed his Department to designate Anthropic a ‘Supply-Chain Risk to National Security,’ and further directed that ‘effective immediately, no contractor, supplier, or partner that does business with the United States military may conduct any commercial activity with Anthropic.’</p>
<p>“These actions are unprecedented and unlawful,” the lawsuit adds. “The Constitution does not allow the government to wield its enormous power to punish a company for its protected speech.”</p>
<p>In response, the White House has <a href="https://www.politico.com/news/2026/03/09/anthropic-sues-trump-admin-over-supply-chain-risk-label-00818716" target="_blank" rel="nofollow">stated</a> that it “will never allow a radical left, woke company to jeopardize our national security by dictating how the greatest and most powerful military in the world operates.”</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>The U.S. will only pull out of Iran when Israel decides it’s time to call it quits.</p>
<p>That’s according to Donald Trump, who told <a href="https://www.timesofisrael.com/trump-to-times-of-israel-itll-be-a-mutual-decision-with-netanyahu-regarding-when-iran-war-ends/" target="_blank" rel="nofollow"><em>The Times of Israel</em></a> on Sunday that the decision to end the Iran war will be a “mutual” decision he makes with Israeli Prime Minister Benjamin Netanyahu.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>“I think it’s mutual … a little bit. We’ve been talking,” Trump said when asked if he alone would make the decision to end the war. “I’ll make a decision at the right time, but everything’s going to be taken into account.”</p>
<p>He dismissed the idea that Israel could continue its own campaign against Iran even after the U.S. pulls back, telling the <em>Times of Israel</em>, “I don’t think it’s going to be necessary.”</p>
<p>“Iran was going to destroy Israel and everything else around it.… We’ve worked together. We’ve destroyed a country that wanted to destroy Israel,” Trump told the paper.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>Trump’s deference to Israel stands in stark contrast to where he supposedly stood on the issue on Friday, when White House press secretary Karoline Leavitt told reporters that the decision to end the war would be <a href="https://newrepublic.com/post/207481/white-house-trump-will-decide-iran-unconditional-surrender" target="_blank" rel="nofollow">solely up to</a> the U.S. president’s discretion.</p>
<p>State Secretary Marco Rubio gave away the game on the rationale for U.S. involvement in the war last week. Speaking to a press huddle, Rubio explained that Israel had forced Trump’s hand in the matter by heedlessly barging forward with its war plans against Iran. That prompted U.S. military assets to strike first, a decision that Rubio chalked up to intel that indicated Iran would retaliate with force against American interests if Israel initiated an attack.</p>
<p>Hours later, Trump decided that messaging was <a href="https://newrepublic.com/post/207352/mike-johnson-donald-trump-enforcing-constitution-iran" target="_blank" rel="nofollow">unacceptable</a>, publicly disagreeing with his secretary of state’s interpretation of events.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>That required Rubio to reemerge before reporters the following day, frantically backpedalling on the explanation he had offered. Mike Waltz, the U.S. ambassador to the United Nations, claimed later the same day that Rubio’s point-blank comments had been “taken out of context.”</p>
<p>Talk of escalating the conflict with Iran has ramped up in recent days amongst chief White House officials, at times doing so in a remarkably disaffected way. The president declared on Friday that he wants “<a href="https://www.aljazeera.com/news/liveblog/2026/3/6/iran-live-trump-says-iran-being-demolished-tehran-keeps-up-gulf-attacks" target="_blank" rel="nofollow">unconditional surrender</a>” from Iran, and would not negotiate a peace deal without it.</p>
<p>Trump and his Republican allies are <a href="https://www.nbcnews.com/politics/white-house/trump-privately-shown-serious-interest-us-ground-troops-iran-rcna262176" target="_blank" rel="nofollow">privately warming</a> to the idea of a U.S. ground invasion in Iran. Meanwhile, Iranian officials have already said they are “<a href="https://www.nbcnews.com/world/iran/iran-foreign-minister-interview-rcna261920" target="_blank" rel="nofollow">confident</a>” the country could counter a U.S. ground invasion.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>So far, seven U.S. soldiers have been killed in the conflict, as have more than 20 Iranian officials, including Ayatollah Ali Khamenei. Eighteen American soldiers have also been seriously injured. More than <a href="https://www.aljazeera.com/news/2026/3/1/us-israel-attacks-on-iran-death-toll-and-injuries-live-tracker" target="_blank" rel="nofollow">1,200 Iranian civilians</a> have been killed, including dozens of children at a girls’ school in the country’s south. A U.S. assessment report found that the strike was “<a href="https://www.cbsnews.com/news/us-iran-war-bombing-girls-school-assessment/" target="_blank" rel="nofollow">likely</a>” the fault of American forces.</p>
</div></div><div class="article-body-wrap"><div class="article-text-wrap article-text-grid">
<p>Republican Representative Andy Ogles decided to write off an entire religious community in America on Monday.</p>
<p>“Muslims don’t belong in American society,” Ogles <a href="https://x.com/RepOgles/status/2031002097135599717" target="_blank" rel="nofollow">posted on X</a>. “Pluralism is a lie.”</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>The Tennessee congressman has a long history of bigoted comments. He said America “<a href="https://newrepublic.com/post/179177/republican-congressman-andy-ogles-kill-them-all-palestinian-children-gaza" target="_blank" rel="nofollow">should kill ’em all</a>” last year regarding Palestinians in Gaza. He called for <a href="https://newrepublic.com/post/181409/gop-congressman-ogles-bill-student-protests-gaza" target="_blank" rel="nofollow">sending</a> pro-Palestine student protesters to Gaza last May, and used footage of September 11 to <a href="https://newrepublic.com/post/202658/republican-congressmen-cruz-fine-ogles-racism-zohran-mamdani-new-york" target="_blank" rel="nofollow">attack</a> Zohran Mamdani before he was elected New York City mayor.</p>
<p>In November, Ogles made a <a href="https://www.msn.com/en-us/news/us/congressman-andy-ogles-makes-a-series-of-anti-muslim-comments-on-podcast/ar-AA1QV0fo?apiversion=v2&amp;domshim=1&amp;noservercache=1&amp;noservertelemetry=1&amp;batchservertelemetry=1&amp;renderwebcomponents=1&amp;wcseo=1" target="_blank" rel="nofollow">series</a> of anti-Muslim comments on his <em>Restoring the Republic</em> podcast, saying, “The only thing they can do is essentially come to our nation and breed their way through our society, and I hate to say that, that’s harsh, it’s going to offend somebody, so what? Wake up.”</p>
<p>What prompted Ogles to post prejudice against Muslims Monday morning isn’t clear, although a protest outside of Mamdani’s mayoral residence in New York on Sunday might have had something to do with it. Anti-Islam provocateur Jake Lang showed up with about 20 protesters outside of Gracie Mansion, only to be met by 125 counterprotesters. Among them were two people allegedly inspired by ISIS who were arrested after <a href="https://www.cnn.com/2026/03/09/us/explosive-device-mayor-mamdani-home-fbi-terrorism-hnk" target="_blank" rel="nofollow">throwing</a> homemade bombs that didn’t explode.</p>
</div>
<div class="article-text-wrap article-text-grid">
<p>If that wasn’t what spurred Ogles’s attack, it could be the war in Iran, or something from one of his four Muslim colleagues in Congress, particularly Representative Ilhan Omar, whom he has <a href="https://www.instagram.com/reel/DSDWaivEZBj/?utm_source=ig_web_copy_link&amp;igsh=NTc4MTIwNjQ2YQ==" target="_blank" rel="nofollow">attacked</a> in the past. Perhaps he should be more worried about the <a href="https://www.newschannel5.com/news/newschannel-5-investigates/federal-criminal-investigation-of-tennessee-congressman-remains-open-new-filing-reveals" target="_blank" rel="nofollow">open federal investigation</a> into his campaign finances or the mounting fact-checks of his <a href="https://www.newschannel5.com/news/newschannel-5-investigates/tennessee-congressman-andy-ogles-didnt-want-you-to-see-his-college-transcript-we-got-it-anyway" target="_blank" rel="nofollow">lies</a> about his background. Ogles should be censured by Congress at a minimum, but bigotry against Muslims in America is sadly considered normal, especially in the Republican Party.</p>
</div></div>]]></description>
      <link>https://newrepublic.com/post/207555/pete-hegseth-billions-dollars-fruit-basket-stands-chairs-crab</link>
      <guid>https://newrepublic.com/post/207555/pete-hegseth-billions-dollars-fruit-basket-stands-chairs-crab</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Noids - Cam Pedersen]]></title>
      <description><![CDATA[<p>Those aren't boids.</p><p>I'm calling them <strong>noids</strong> - neural boids. No hand-written rules. A small neural network takes in what each agent can see and outputs a steering force. 1,922 learned parameters. That's the entire program!</p><p>But before I explain how they work, I want to talk about real birds.</p><h2>How real birds flock</h2><p><img alt="Starling murmuration" width="800" height="600" data-nimg="1" class="c10" sizes="100vw" srcset="/_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=640&amp;q=75 640w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=750&amp;q=75 750w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=828&amp;q=75 828w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=1080&amp;q=75 1080w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=1200&amp;q=75 1200w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=1920&amp;q=75 1920w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=2048&amp;q=75 2048w, /_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=3840&amp;q=75 3840w" src="https://campedersen.com/_next/image?url=%2Fnoid%2Fmurmuration.gif&amp;w=3840&amp;q=75" /></p><p>A starling murmuration can have 300,000 birds. No leader. No choreography. No bird knows the shape of the flock. And yet the whole mass moves as one, rippling and folding, evading a falcon in coordinated waves that propagate faster than any single bird can fly.</p><p>For decades, people assumed this required some kind of global signal. A lead bird. A pheromone. Something. But the real mechanism is local. Each bird adjusts its velocity to stay close to its nearest handful of neighbors, match their heading, and avoid collision. Local perception. Local action. The murmuration is what you get when 300,000 agents do this simultaneously.</p><p>No one tells the flock to turn. A turn starts when a few birds on the edge react to a predator. Their neighbors notice the change and adjust. Their neighbors' neighbors adjust. The correction propagates through the flock like a compression wave, at speeds 3-4x faster than any individual bird. It's not communication. It's physics. The same way sound moves through air: each molecule only bumps the ones next to it, but the wave crosses the room.</p><p>Click anywhere near the flock to startle it. Watch how the reaction spreads. The noids you hit scatter first, and the rest follow a beat later as the disturbance propagates through their neighbor connections.</p><div class="c13"><p>click anywhere to startle the flock</p></div><h2>From birds to boids to noids</h2><img src="https://campedersen.com/noid/reynolds.jpg" alt="Craig Reynolds" class="c14" /><p>In 1986, <a href="https://www.red3d.com/cwr/boids/" target="_blank" rel="noreferrer">Craig Reynolds</a> guessed at what each bird might be doing and encoded it as three rules:</p><ol><li><strong>Separation</strong>: steer away from neighbors that are too close</li>
<li><strong>Alignment</strong>: match the average heading of nearby neighbors</li>
<li><strong>Cohesion</strong>: steer toward the average position of nearby neighbors</li>
</ol><p>He called the agents <em>boids</em>. It worked! With three rules and some weight tuning, you get convincing flocking on a screen. Every boid simulation since, in games, films, screensavers, is some variation of Reynolds' three rules.</p><p>Two decades later, in 2010, a team led by Andrea Cavagna at the University of Rome tracked individual starlings in 3D using multiple synchronized cameras. They reconstructed the position and velocity of every bird in flocks of over a thousand, and confirmed that the local-interaction model was right. They also found something Reynolds didn't predict: each bird tracks about <strong>6-7 neighbors</strong>. Not "every bird within 5 meters" but "my nearest 7, however far they are." This is called <strong>topological distance</strong> rather than metric distance, and it matters. A metric rule breaks down when the flock stretches thin, because suddenly you have zero neighbors in range. A topological rule doesn't. Whether your 7th neighbor is 2 meters away or 20, you still track exactly 7.</p><p>But Reynolds had to invent the rules. He had to decide that there should be exactly three. He had to pick the mathematical form of each one: inverse distance for separation, averaging for alignment. He had to tune the weights by hand.</p><p>What if you didn't have to do any of that? What if you just gave each agent a perception of its neighbors, the same local view a real starling has, and let a neural network learn the steering function from data?</p><p>That's a noid! Delete the rules. Keep the perception. Learn the rest.</p><h2>What a neural network actually does</h2><p>Every neural network is a function. Input goes in, output comes out. The weights determine <em>which</em> function. Training finds the right weights for your task.</p><p>Most examples of this are too complex to see clearly. Language models have billions of parameters. Image classifiers operate in thousand-dimensional space. The mechanics are the same, but the scale hides the intuition.</p><p>A noid is a neural network you can actually watch. 24 numbers in, 2 numbers out. The input is what the noid perceives. The output is what it does. The function between them, shaped by 1,922 weights, is its entire behavior.</p><div class="c13"><p>hover any node to inspect. blue negative, gold positive</p></div><h2>What a noid sees</h2><p>Real starlings track ~7 neighbors by topological rank. A noid tracks 5. Same idea, slightly smaller neighborhood. Each noid encodes:</p><ul><li>Its own velocity: <code>[vx, vy]</code></li>
<li>Its heading: <code>[sin θ, cos θ]</code></li>
<li>Its 5 nearest neighbors, relative position and velocity: <code>[Δx, Δy, Δvx, Δvy]</code> × 5</li>
</ul><p>24 numbers. That's the entire universe from a noid's perspective!</p><div class="c13"><p>gold = focus noid blue = 5 nearest neighbors arrow = network output</p></div><p>The gold noid is the one we're watching. The blue connections show its 5 nearest neighbors, the only agents it knows about. The red arrow is the network's output: a 2D acceleration that steers it through the flock.</p><p>No noid knows where it is in absolute space. No noid can count the flock. No noid knows the flock's shape, or that there even is a shape. Just local perception feeding into a function that outputs a push. Same as a starling.</p><p>This is the design choice that matters most. Not the network architecture. Not the training algorithm. <strong>What you choose to perceive determines what you can learn.</strong> Cavagna's team proved that real birds use topological neighbors. That's the foundation everything else builds on.</p><h2>The network</h2><div class="c26"><div class="c17">obs24Linear32SiLULinear32SiLULinear2tanh×608001,05666<p>1,922 parameters total. hover or click a layer.</p></div><div class="c22"><div data-idx="0" class="c20"><p class="c18"><strong>24 numbers.</strong> That's everything a noid knows. Its own velocity (2 floats), its heading (2 floats), and its 5 nearest neighbors as relative position and velocity (4 floats × 5). No absolute position. No flock size. Just local perception.</p><p>vxvysincosn1: Δx Δy Δvx Δvyn2: Δx Δy Δvx Δvyn3: Δx Δy Δvx Δvyn4: Δx Δy Δvx Δvyn5: Δx Δy Δvx Δvy</p></div><div data-idx="1" class="c20"><p class="c18">A 24×32 weight matrix plus 32 biases. <strong>800 parameters.</strong> Each of the 32 outputs is a different weighted combination of all 24 inputs. The network learns which combinations matter: the angle to the nearest neighbor, the relative speed of the group, the closing distance to a collision. This is where raw perception becomes features.</p></div><div data-idx="2" class="c20"><p class="c18">Without activations, stacking linear layers would be pointless: two matrix multiplies collapse into a single matrix. <strong>SiLU</strong> (x · sigmoid(x)) breaks that linearity. It suppresses small signals, amplifies large ones, and lets the network carve curved decision boundaries instead of straight lines. This is where a stack of arithmetic becomes a function approximator.</p>x·σ(x)</div><div data-idx="3" class="c20"><p class="c18">32×32 weight matrix plus 32 biases. <strong>1,056 parameters</strong>, over half the network. The first layer asks "what do I see?" This layer asks "what does it mean?" It combines first-layer features into higher-order patterns: not just "neighbor is close" but "neighbor is close <em>and</em> approaching <em>and</em> I'm heading toward it." Another SiLU follows, gating this deeper representation.</p></div><div data-idx="4" class="c20"><p class="c18">The final layer collapses 32 dimensions to 2: an x-acceleration and a y-acceleration. <strong>66 parameters.</strong> Then <code>tanh</code> squashes the result to [−1, 1] and ×60 scales it to match the physics. No matter what the network computes internally, steering force is bounded. A noid has limited thrust, same as a real bird.</p>+60−60tanh</div></div><div class="c25"><p class="c23">1,922 parameters total. You could fit a flock's entire social contract in a QR code.</p><a href="https://www.youtube.com/watch?v=G7hhowYtBuE" target="_blank" rel="noopener noreferrer" title="Watch a starling murmuration" class="c24"></a></div></div><h2>How training works</h2><p>The network learns by imitating Reynolds' three rules. Generate random flock configurations. For each noid, compute what the classic rules would do. Then adjust the network's weights to match.</p><p>This is called <strong>imitation learning</strong>, also known as behavioral cloning. You have an expert (the hand-tuned rules). You have a student (the neural network). The student watches the expert act and learns to copy it. The same technique is used to train self-driving cars from human demonstrations and to teach robots from teleoperation.</p><p>The loss function is simple: how far off was the network's acceleration from the target?</p><p>L=12∑(apredicted−atarget)2L = \frac{1}{2}\sum(a_{\text{predicted}} - a_{\text{target}})^2L=21​∑(apredicted​−atarget​)2</p><p>Backpropagation computes how each of the 1,922 weights contributed to the error. Gradient descent nudges them in the right direction. Repeat a few thousand times.</p><p>The noids in this post were trained live in your browser when the page loaded. 3,000 gradient steps, done before the first frame rendered. The network is so small that training it takes less time than loading a web font!</p><h2>From chaos to order</h2><p>This is the part I can't stop thinking about!</p><p>Random weights produce chaos. Every noid accelerating nonsensically. Trained weights produce flocking. But weight space is continuous. You can linearly interpolate between the two sets of weights and watch the transition happen in real time.</p><div class="c13"><p>chaosorder</p></div><p>At zero, noise. Random accelerations, no coherence. Around 0.3, the first hints of local alignment, pairs of noids briefly synchronizing before the noise pulls them apart. By 0.6, clusters form. By 0.8, it's unmistakably a flock!</p><p>This is a phase transition in weight space. 1,922 floats, smoothly varied, and at some critical threshold collective behavior clicks on. The network doesn't have a "flocking" switch. There's no single weight that enables it. The behavior is distributed across all 1,922 parameters, and it emerges from their interaction.</p><p>This is how all neural networks work. There's no neuron in GPT that stores the concept of "irony." There's no pixel detector in a vision model. The behavior is distributed across all the weights, emerging from their interaction. Noids make this visible because the system is small enough to watch.</p><h2>The starling lesson</h2><p>A starling doesn't know Reynolds' three rules. It doesn't separate, then align, then cohere in three discrete steps. It sees its neighbors and it moves. Whatever algorithm runs in a starling's brain, it wasn't hand-decomposed into named subroutines by a programmer.</p><p>That's what a noid captures that a boid doesn't. A boid is three rules bolted together. A noid is a single learned function, perception in, action out, with no explicit decomposition into separation, alignment, and cohesion. Those behaviors emerge from the weights, the same way they emerge from whatever neural circuitry a starling uses.</p><p>The architecture mirrors the biology: topological neighbors, local perception, a nonlinear mapping to motor output, no global state. We don't know the exact function a starling computes. But we know the <em>form</em> of it. And a noid is a 1,922-parameter hypothesis about what that function might look like.</p><h2>Performance</h2><p>1,024 noids · cpu · --</p><p>A neural network forward pass is a matrix multiplication. Matrix multiplication is what GPUs do. The entire flock's inference, all 1,024 forward passes, collapses into a single GPU dispatch: <code>[1024 × 24] @ [24 × 32]</code>. One call. Every agent in parallel.</p><p>Classic boid rules can't do this. Separation needs per-agent distance comparisons. Alignment averages conditionally. Cohesion divides by neighbor count. The logic branches per agent, which GPUs hate.</p><p>On CPU, the cost breakdown looks like this:</p><table><thead><tr><th>
</th><th>noid</th>
<th>boid</th>
</tr></thead><tbody><tr><td>steering (per agent)</td>
<td>527 ns</td>
<td>13 ns</td>
</tr><tr><td>full tick, n=1024</td>
<td>1.9 ms</td>
<td>1.1 ms</td>
</tr><tr><td>full tick, n=4096</td>
<td>17 ms</td>
<td>14 ms</td>
</tr></tbody></table><p>The steering itself is 40x more expensive. But neighbor search (O(n) with spatial hashing) dominates the total, so the gap shrinks to 1.2x at scale. The neural network adds a 20% tax on CPU.</p><p>On GPU, that 527 ns per agent becomes a single dispatch for all agents simultaneously. The 1,856 multiply-adds per agent map directly to shader cores. The inference in the demo above runs on your GPU via WebGPU if your browser supports it (check the badge in the corner). On CPU fallback, it still hits 60fps at 1,024 agents thanks to spatial hashing.</p><p>This is the real argument for neural flocking. Not that the rules are better (Reynolds' three rules work great). But that the computational form, matrix multiplications on fixed-size tensors, maps to hardware that already exists in every phone, laptop, and GPU. The same hardware that runs language models and image generators can run a flock. The noid forward pass is the same operation as a single attention head, just smaller.</p><h2>The library</h2><p><a href="https://github.com/ecto/noid" target="_blank" rel="noreferrer">noid</a> is open source. Self-contained Rust crate. No framework, no GPU requirement.</p><div class="code-block-wrapper"><pre>use noid::{Config, Flock};
let mut flock = Flock::new(Config::default(), 42);
loop {
    flock.tick(1.0 / 60.0);
    for pos in &amp;flock.positions {
        // render at pos[0], pos[1]
    }
}</pre></div><p>Training is built in:</p><div class="code-block-wrapper"><pre>use noid::train::Trainer;
let mut trainer = Trainer::new(Config::default(), 42);
for _ in 0..5000 {
    trainer.step(0.001);
}
trainer.brain().save_json();</pre></div><p>Weight interpolation too:</p><div class="code-block-wrapper"><pre>use noid::Brain;
let chaos = Brain::random(42);
let order = Brain::load_json(include_str!("weights.json"));
let halfway = Brain::lerp(&amp;chaos, &amp;order, 0.5);</pre></div><p>300,000 starlings. 7 neighbors each. No leader.</p><p>1,024 noids. 5 neighbors each. 1,922 weights. One GPU dispatch.</p><p>Same idea.</p><p><strong>Corrections</strong></p><p><em>2026-03-09:</em> Restructured the "How real birds flock" section. The original version presented Cavagna's 2010 research before Reynolds' 1986 boids, making it read like Reynolds traveled forward in time. Reynolds now comes first historically, with Cavagna's topological distance findings presented as the later confirmation they were. Also clarified topological vs metric distance wording. Thanks to the readers who flagged both issues.</p>]]></description>
      <link>https://campedersen.com/noid</link>
      <guid>https://campedersen.com/noid</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Every Single Board Computer I Tested in 2025 - bret.dk]]></title>
      <description><![CDATA[<blockquote>I benchmarked 15 SBCs released in 2025 across every price point. Here's what stood out, what disappointed, and what the year looked like for single board computers.</blockquote>]]></description>
      <link>https://bret.dk/every-single-board-computer-i-tested-in-2025/</link>
      <guid>https://bret.dk/every-single-board-computer-i-tested-in-2025/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The lawyers and scientists training AI to steal their careers | The Verge]]></title>
      <description><![CDATA[<header class="ca4k810 _2rtmtw0"><div class="_2rtmtw1">
<p class="_2rtmtw4">Laid-off lawyers, history PhDs, and scientists are now part of a miserable gig economy in which they’re teaching AI how to do their old jobs. If you’re still employed…</p>
<div class="_2rtmtw6">
<p class="title-font _2rtmtw8">by Josh Dzieza</p>
<p class="_2rtmtw9">Art by Samar Haddad</p>
</div>
<div class="_2rtmtw6 _2rtmtw7">
<div class="title-font _2rtmtwa"><time datetime="2026-03-10T09:00:01+00:00">Mar 10, 2026, 9:00 AM GMT</time></div>
</div>
</div>
</header><div class="qhtfy44">
<p class="body-text _92t5a10">This article is a collaboration between The Verge and <a href="https://nymag.com/intelligencer/article/white-collar-workers-training-ai.html" target="_blank" rel="noopener noreferrer">New York Magazine</a>.</p>
<div>
heThe LinkedIn post seemed like yet another scam job offer, but Katya was desperate enough to click. After college, she’d struggled to make a living as a freelance journalist, gone to grad school, then pivoted to what she hoped would be a more stable career in content marketing — only to find AI had automated much of the work. This company was called Crossing Hurdles, and it promised copywriting jobs starting at $45 per hour.
<p class="duet--article--article-body-component z1fbk00 body-text">Katya clicked and was taken to a page for another company, called Mercor, where she was instructed to interview on-camera with an AI named Melvin. “It just seemed like the sketchiest thing in the world,” Katya says. She closed the tab. But a few weeks later, still unemployed, she got a message inviting her to apply to Mercor. This time, she looked up the company. Mercor, it seemed, sold data to train AI, and she was being recruited to create that data. “My job is gone because of ChatGPT, and I was being invited to train the model to do the worst version of it imaginable,” she says. The idea depressed her. But her financial situation was increasingly dire, and she had to find a new place to live in a hurry, so she turned on her webcam and said “hello” to Melvin.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">It was a strange, if largely pleasant, experience. Manifesting on Katya’s laptop as a disembodied male voice, Melvin seemed to have actually read her résumé and asked specific questions about it. A few weeks later, Katya, who like most workers in this story asked to use a pseudonym out of fear of retaliation, received an email from Mercor offering her a job. If she accepted, she should sign the contract, submit to a background check, and install monitoring software onto her computer. She signed immediately.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">She was added to a Slack channel, where it was clear she was entering a project already underway. Hundreds of people were busy writing examples of prompts someone might ask a chatbot, writing the chatbot’s ideal response to those prompts, then creating a detailed checklist of criteria that defined that ideal response. Each task took several hours to complete before the data was sent to workers stationed somewhere down the digital assembly line for further review. Katya wasn’t told whose AI she was training — managers referred to it only as “the client” — or what purpose the project served. But she enjoyed the work. She was having fun playing with the models, and the pay was very good. “It was like having a real job,” she says.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Two days after Katya started, the project was abruptly paused. A few days after that, a supervisor popped into the room to let everyone know it had been canceled. “I’m working assuming that I can plan around this. I’m saving up for first and last month’s rent for an apartment,” Katya says, “and then I’m back on my ass. No warning, no security, nothing.” Several days later, she got an email from Mercor with another offer, this one for a job evaluating what seemed to be conversations between chatbots and real users — many appeared to be from people in Malaysia and Vietnam practicing English — according to various criteria, like how well the chatbot followed instructions and the appropriateness of its tone. Sign the contract, the email said, and you’ll have a Zoom onboarding call in 45 minutes. It was 6:30PM on a Sunday night. Scarred from the abrupt disappearance of the previous gig, she accepted the offer and worked until she couldn’t stay awake.</p>
<figure class="_1nqd5v80">
</figure><p class="duet--article--article-body-component z1fbk00 body-text">Machine-learning systems learn by finding patterns in enormous quantities of data, but first that data has to be sorted, labeled, and produced by people. ChatGPT got its startling fluency from thousands of humans hired by companies such as Scale AI and Surge AI to write examples of things a helpful chatbot assistant would say and to grade its best responses. A little over a year ago, concerns began to mount in the industry about a plateau in the technology’s progress. Training models based on this type of grading yielded chatbots that were very good at sounding smart but still too unreliable to be useful. The exception was software engineering, where the ability of models to automatically check whether bits of code worked — did the code compile, did it print HELLO WORLD — allowed them to trial-and-error their way to genuine competence.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">The problem was that few other human activities offer such unambiguous feedback. There are no objective tests for whether financial analysis or advertising copy is “good.” Undeterred, AI companies set out to make such tests, collectively paying billions of dollars to professionals of all types to write exacting and comprehensive criteria for a job well done. Mercor, the company Katya stumbled upon, was founded in 2023 by three then-19-year-olds from the Bay Area, Brendan Foody, Adarsh Hiremath, and Surya Midha, as a jobs platform that used AI interviews to match overseas engineers with tech companies. The company received so many inquiries from AI developers seeking professionals to produce training data that it decided to adapt. Last year, Mercor was valued at $10 billion, making its trio of founders the world’s youngest self-made billionaires. OpenAI has been a client; so has Anthropic.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Each of these data companies touts its stable of pedigreed experts. Mercor says around 30,000 professionals work on its platform each week, while Scale AI claims to have more than 700,000 “M.A.’s, Ph.D.’s, and college graduates.” Surge AI advertises its Supreme Court litigators, McKinsey principals, and platinum recording artists. These companies are hiring people with experience in law, finance, and coding, all areas where AI is making rapid inroads. But they’re also hiring people to produce data for practically any job you can imagine. Job listings seek chefs, management consultants, wildlife-conservation scientists, archivists, private investigators, police sergeants, reporters, teachers, and rental-counter clerks. One recent job ad called for experts in “North American early to mid-teen humor” who can, among other requirements, “explain humor using clear, logical language, including references to North American slang, trends, and social norms.” It is, as one industry veteran put it, the largest harvesting of human expertise ever attempted.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">These companies have found rich recruiting ground among the growing ranks of the highly educated and underemployed. Aside from the 2008 financial crash and the pandemic, hiring is at its lowest point in decades. This past August, the early-career job-search platform Handshake found that job postings on the site had declined more than 16 percent compared with the year before and that listings were receiving 26 percent more applications. Meanwhile, Handshake launched an initiative last year connecting job seekers with roles producing AI training data. “As AI reshapes the future of work,” the company wrote, announcing the program, “we have the responsibility to rethink, educate, and prepare our network to navigate careers and participate in the AI economy.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">There is an underlying tension between the predictions of generally intelligent systems that can replace much of human cognitive labor and the money AI labs are actually spending on data to automate one task at a time. It is the difference between a future of abrupt mass unemployment and something more subtle but potentially just as disruptive: a future in which a growing number of people find work teaching AI to do the work they once did. The first wave of these workers consists of software engineers, graphic designers, writers, and other professionals in fields where the new training techniques are proving effective. They find themselves in a surreal situation, competing for precarious gigs pantomiming the careers they’d hoped to have.</p>
achEach of the more than 30 workers I spoke with occupied a position along a vast and growing data-supply chain. There are people crafting checklists that define a good chatbot response, typically called “rubrics,” and other people grading those rubrics. Others grade chatbot answers <em>according</em> to those rubrics, and still others take the rubrics and write out what’s often described as a “golden output,” or the ideal chatbot answer. Others are asked to explain every step they took to arrive at this golden output in the voice of a chatbot thinking to itself, producing what’s called a “reasoning trace” for AI to follow later when it encounters a similar task out in the real world.
<p class="duet--article--article-body-component z1fbk00 body-text">Sometimes the labs want only rubrics for prompts their AI can’t already do, which means companies like Mercor ask workers to produce “stumpers,” or requests that will make the model fail. “It sounds easy, but it’s really hard,” says a worker who was trying to stump models by asking them to make inventory-management dashboards. Models fail in counterintuitive ways. They may be able to solve advanced-physics exam questions, but ask them for transit directions and they’ll recommend transferring on nonconnecting train lines. Finding these weak spots takes time and creativity.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">One type of project gathers groups of lawyers, human-resources managers, teachers, consultants, or bankers for something Mercor calls world-building. “You and your team will role-play a real-life team within your profession,” the training materials read. The teams are given dedicated emails, calendars, and chat apps and asked to create a hundred or more documents that would be associated with some corporate undertaking, like a fictional mining company analyzing whether to enter the data-center business.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">After several 16-hour days of fantasy document production, one worker recounts, the resulting slide decks, meeting notes, and financial forecasts are sent to another team, which uses them as grist in their attempts to stump a model operating in this simulated corporate environment. Then, having stumped the model, that team writes new, more nuanced rubrics, golden answers, and so on. Workers can only guess who the customer is or how many others are working on the project — based on references to teams like Management Consulting World No. 133, there could be hundreds, maybe thousands.</p>
<figure class="_1nqd5v80">
</figure><p class="duet--article--article-body-component z1fbk00 body-text">There are people hired to evaluate the ability of image models to follow their prompts and others who summarize video clips in extraordinary detail, presumably to train video models. Efforts to improve AI’s ability to have spoken conversations have resulted in a surging demand for voice actors, who might find themselves recording “authentic, emotionally resonant” speeches, according to one listing. “I just tell people I’m an AI trainer, then it sounds more professional than what I’m doing,” says an aspiring screenwriter who was instructed to record himself pretending to ask a chatbot for a fitness plan while pots and pans clanged in the kitchen. Another time, he was told to record himself dispensing financial advice over the phone to a parade of people he assumed were other workers.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">This audio might then be broken down and sent to someone like Ernest, who used to make a living as an online tutor until the company he worked for replaced him with a chatbot. When we spoke, he was listening to minutelong clips of random dialogue slowed to 0.1x speed and marking when someone started and stopped speaking down to the millisecond. Many of the clips included a person talking with a chatbot and interjecting “huh” or “I see,” so he assumes he was improving AI’s ability to have naturally flowing conversation, but he has no actual idea.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">As is standard practice in the field, the project was referred to by a codename and the client only ever as “the client.” The entire system is designed so that workers have minimal insight into the supply chain they are part of. If they find out who the customer is, they are contractually forbidden from telling anyone, even their own colleagues. Nor are they allowed to describe the details of their work beyond broad generalities like “providing expertise in XYZ domain to improve models for a top AI lab,” according to one Mercor agreement. So afraid are workers of inadvertently violating their confidentiality agreements and getting fired that when they discuss their work in public forums, they mask their already codenamed projects with additional codenames, for example by referring to a project called “Raven” as “Poe.”</p>
<blockquote class="mal5830">
<div class="mal5831">
<div class="mal5832">“I’m being handed a shovel and told to dig my own grave.”</div>
</div>
</blockquote>
atya’sKatya’s second project with Mercor was far more stressful. There was less work to go around, and it came in fits and starts. Managers would drop a message in the Slack channel saying new tasks were incoming in half an hour, and, she says, “everyone in Slack would drop what they were doing and jump on them like piranhas,” working as fast as they could while the bar showing how many tasks remained slid toward zero. Then they were back in Slack again, politely begging supervisors for more work and more hours, talking about their kids’ birthdays or their need to pay rent, or telling anyone who might be listening that their availability was wide open in case there was more work to be done. Soon, Katya was dropping everything at the sound of a Slack ding too. “Sometimes I’m on the toilet or at dinner and I get the Slack notification. I’m like, ‘Oh, sorry, I gotta work now.’”
<p class="duet--article--article-body-component z1fbk00 body-text">That project soon ended and then came another. It was nearly identical to the first, which she had enjoyed, but now, on top of writing rubrics, she had to stump the model and complete the more difficult task in the same amount of time. She was also getting paid $8 an hour less. This is common at Mercor. Nearly every worker I spoke with reported that demands increased, time requirements shrank, and pay decreased as projects continued. Those who couldn’t meet the new demands got “offboarded” and replaced by new recruits.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Chris joined Mercor last year, after a difficult few months struggling to find film work. Unlike many people who suspect they’re casualties of automation, he knew for certain that this was the case. He’d had a recurring job drafting episodes for an unscripted television show — doing preinterviews, sketching scenes, writing the reality TV equivalent of a screenplay. But in late 2024, he was told the show would be running on a “skeleton crew” and his work was no longer needed. He found out later the company was using ChatGPT to draft new episodes. So that October, when Chris received an offer to write an entire sci-fi screenplay for a major AI company, he said “yes,” grim as the prospect was. Since then, he has gone from gig to gig. “This is my only source of income right now,” he says. “I know people who are award-winning producers and directors, and they’re not advertising that they’re doing this work, but that’s how they’re putting food on the table.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">His first jobs with Mercor were, like Katya’s, relatively pleasant and well paid, but soon came the 6PM fist-bump-emoji Slack exhortations to “come on team, let’s push through this,” followed by sudden halts and months of silence. “You were just constantly waiting for the crack of the starting gun at any hour of the day,” Chris says. Then it was crunch time again and managers, increasingly panicked as deadlines neared, started threatening workers with offboarding if they didn’t complete tasks quickly enough.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">The time he spent working was tracked to the second by software called Insightful, which monitored everything he did on his computer. Time that the software deems “unproductive” could be deducted from his pay, and if a few minutes passed without him typing, the system pinged him to ask whether he had been working. Sometimes Chris saw people post in Slack that they’d gone over the target time on a particularly tricky task and that they hoped it would be okay; the next day, they would be gone.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Increasingly worried he would be offboarded too, he started working off the clock, deactivating Insightful while reading instructions so he could move faster. If he went over the target time, he turned the clock off and kept working for free.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Companies say this software is necessary to accurately track hours and prevent workers from cheating, which, in this case, means using AI, something all data companies strictly forbid. The ground truth of verified human expertise is what they’re selling, and when AI trains on AI-generated data, it gradually degrades, a phenomenon researchers call “model collapse.” Employees of data companies say it is a constant battle to screen out AI slop. For workers, AI is a particular temptation as pressure increases. When the retail expert trying to stump models with analytics dashboards had her target time dropped from eight hours per task to five to three and a half, she turned off Insightful and sought outside help. “To be honest, I went into Copilot and ChatGPT and put my prompt in there and said, ‘How can I work this so you guys can’t answer it?’” Then she went to another chatbot and asked if the prompt sounded AI generated and, if so, to make it sound more human.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“It’s just so horrible, the mental effect of it,” says Mimi, a screenwriter who has worked on multiple streaming shows and has been training AI for Mercor for several months. She found out about Mercor from a fellow screenwriter who dropped one of its job links in a Writers Guild of America Facebook group.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Like a lot of people in this line of work, Mimi is conflicted. “One documentary-maker who’s won Emmys, he messaged me and he was like, ‘I’m being handed a shovel and told to dig my own grave,’ and that’s exactly how everyone thinks about it,” she says. Still, as a single mom, she needed the money. She was thankful for the work at first, then the project was paused, unpaused, and paused again. For five weeks, she was told a project would be starting imminently. When it finally did, requirements were added, while the expected time shortened, and she raced to keep up under the watchful eye of Insightful. She felt that someone put it well on Slack when they said it was like they were living in a fishbowl waiting for their human masters to drop in food, and only the ones who were fast enough to swim to the top could eat.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“Last night, I got so fucking stressed because my kid came home and it was 7PM, and I get this message, ‘The tasks are out!’ and I’m just working, just trying to get as many hours in before I can go to bed,” Mimi says, choking up. “I spend no time with my kid, and at one point, he can’t find something for school and I just start screaming at him. This work is turning me into a fucking demon.” She’s especially disturbed by the surveillance: “The idea that somebody can measure your time and that all the little bits that go into being a human are taken away because they’re not profitable, that you can’t charge for going to the toilet because that’s not time you’re working, you can’t charge for making a cup of coffee because that’s not time you’re working, you can’t charge for having a stretch because your back hurts. This is why unions were formed, so people could have guaranteed hours and guaranteed lunch breaks and guaranteed holidays and sick pay. This is the gig economy to the very extreme.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">This is what concerns her more than the AI itself: that it’s bringing to knowledge work the sort of precarious platform labor that has transformed taxi driving and food delivery. Meanwhile, she watches in horror the desperate gratitude of her colleagues as they rejoice at the 7PM announcement of incoming work.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“How long are these tasks expected to last?” one worker asked in Slack.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“I’m wondering too, I’d like to know whether I can sleep or not.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">With no answer forthcoming, they swapped tips on how to stave off sleep.</p>
<blockquote class="mal5830">
<div class="mal5831">
<div class="mal5832">“Nobody knows what’s going on. Everybody’s really confused.”</div>
</div>
</blockquote>
henWhen Mercor began recruiting aggressively last year, it framed itself as a more worker-friendly version of the platforms that had come before it. Criticizing his rival Scale AI on a podcast, Foody, Mercor’s CEO, said, “Having phenomenal people that you treat incredibly well is the most important thing in this market.” Workers who joined during this time do report being treated well; the pay was better than elsewhere, and instead of being managed by opaque algorithms, as is common, there were actual human supervisors they could go to with questions.
<p class="duet--article--article-body-component z1fbk00 body-text">But people who have worked in management at data companies say they often start out this way, wooing workers off incumbent platforms with promises of better treatment, only for conditions to degrade as they compete to win eight-figure contracts doled out by the half-dozen AI companies who are interested in buying this data in bulk. At Mercor, there was the additional complication of management largely consisting of people in their 20s with minimal work experience who had been given hundreds of millions of investor dollars to pursue rapid growth.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“I don’t care if somebody’s 21 and they’re my manager,” says Chris, the reality TV producer. “But they’ve never worked at this scale. When you try to find some kind of guidance in Slack, very maturely and clearly explaining what the situation is, you get a meme back with a corgi rolling its eyes and it says, ‘Use your judgment.’ But it’s like, ‘Use your judgment and fuck it up, and you get fired.’ You went to Harvard, you graduated last year, and your guidance for a group of people, many of whom are experienced professionals, is a meme?”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Lawyers, designers, producers, writers, scientists — all complained of inexperienced managers giving contradictory instructions, demanding long hours or mandatory Zoom meetings for ostensibly flexible work, and threatening people with offboarding for moving too slowly, threats that were particularly galling for mid-career professionals who felt their 20-year-old bosses barely understood the fields they were trying to automate.</p>
<figure class="_1nqd5v80">
</figure><p class="duet--article--article-body-component z1fbk00 body-text">“The founders pride themselves on ‘9-9-6,’” says a lawyer, referring to a term that originated in China to describe 72-hour workweeks associated with burnout and suicide but has been appropriated by Silicon Valley as aspirational. “You need to be accessible at all hours, and they’re going to pump out messages at 6AM, and you better jump because the perception is you will be offboarded and another person will replace you.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“It’s not just that team leads are young, project managers are young, senior project managers are young. It’s that the senior-senior project managers, the ones responsible for the project in its entirety, are young. I guess that comes from the top because <em>they’re</em> young, right?” says Lindsay, a graphic designer and illustrator in her 50s who came to Mercor after 85 percent of her work evaporated over the past year, owing, she believes, to improvements in generative AI.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Increasingly desperate for work, she scoured job boards; it seemed the only listings matching her expertise were offers to help build the technology she blamed for demolishing her career. “I swallowed my hatred and signed up,” she says. After some initial work producing graphic-design data, she was invited to join a job for Meta grabbing videos from Instagram Reels and tagging whatever was in them. It was boring, and at $21 per hour, the pay was middling, but Lindsay needed the money. So, she discovered when she was brought into the project’s Slack, did approximately 5,000 others.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">In early November, a Mercor representative announced that Lindsay’s project would be ending owing to “scope changes,” though workers had previously been told the project would run through the end of the year. Lindsay and thousands of others found themselves removed from the company’s Slack.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Soon, an email arrived in their inbox, inviting them to a new project called Nova paying $16 per hour.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Thousands of workers poured into the new Slack only to discover it was the exact same job, now paying 24 percent less. All but two of the Slack channels had been deleted, including the watercooler, support, and help rooms. The ability to direct-message one another had also been cut off. There were no team leads to be found. With no one to ask for assistance, workers flooded the main rooms with pleas and indignation.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“Nobody knows what’s going on. Everybody’s really confused,” says Lindsay. “The messages are coming so fast in that channel. It’s just absolute chaos. ‘Help, please. What do I do? What am I supposed to do? Where do I go? Can I get started tasking? Am I supposed to redo all the assessments that I’ve done before?’”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Someone emailed support asking for help, and for some reason that email was sent to every one of the thousand-some people on the project, who seized on it and began to reply-all with their bafflement and outrage. “It was absolute carnage,” says Lindsay. “There’s no other word for it.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Workers began posting complaints on Mercor’s subreddit, only to have their posts quickly deleted by the Mercor representatives who moderate it. In response, two unsanctioned Mercor subreddits were created, where workers could freely express such sentiments as “CHILDREN RUN THIS COMPANY, THEY WILL SOON HAVE THEIR DAY OF RECKONING.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“It’s just really sad,” says Lindsay. “There are some people in there where it’s genuinely the difference between them being able to feed their families and not feed their families.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">“I hate gen AI,” she adds. “I think AI should be used for curing cancer. I think it should be used for space exploration, not in the creative industries. But I need to be able to pay my rent. And then when people like Mercor pull this stuff where they treat you like nothing more than a lab rat — I’ve been working for a very long time. I have never, ever been treated as badly as this.”</p>
ntermittentIntermittent work, extreme secrecy, and abrupt firings are the norm across the data industry. On Surge AI’s work platform, called Data Annotation Tech, workers are not only regularly terminated without explanation; they are often not even told they’ve been fired. They just log in one day and find the dashboard empty of tasks. The phenomenon is so ubiquitous they call it simply “the dash of death.”
<p class="duet--article--article-body-component z1fbk00 body-text">Last year, a Texan with a master’s degree in divinity who was teaching voice models to respond to queries with appropriate levels of feeling — different tones for a user telling them their dog died versus asking for a trip itinerary — logged in to work one morning and found his dashboard empty. Scrolling to the bottom of the page for the support button, he discovered it no longer worked. That’s when he knew he had been terminated. His mind raced through possible reasons: Had he worked too much? Had his quality slipped? He knew he would never find out. “I felt cut adrift,” he says. Anxious about how he would pay his bills and care for his ailing dog, he grew depressed, then horrified. He thought about his teacher friends who couldn’t get their students to write and all the people graduating with now-worthless computer-science degrees. “The technology makes us see everything as a utility, something to be used,” he says, a category that he feels includes discarded data workers like himself. He resolved to become a chaplain, figuring that no matter what the AI future holds, people will need a fellow human to be there for them.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">The on-again, off-again nature of the work is not just the result of company culture; it stems from the cadence of AI development itself. People across the industry described the pattern. A model builder, like OpenAI or Anthropic, discovers that its model is weak on chemistry, so it pays a data vendor like Mercor or Scale AI to find chemists to make data. The chemists do tasks until there is a sufficient quantity for a batch to go back to the lab, and the job is paused until the lab sees how the data affects the model. Maybe the lab moves forward, but this time, it’s asking for a slightly different type of data. When the job resumes, the vendor discovers the new instructions make the tasks take longer, which means the cost estimate the vendor gave the lab is now wrong, which means the vendor cuts pay or tries to get workers to move faster. The new batch of data is delivered, and the job is paused once more. Maybe the lab changes its data requirements again, discovers it has enough data, and ends the project or decides to go with another vendor entirely. Maybe now the lab wants only organic chemists and everyone without the relevant background gets taken off the project. Next, it’s biology data that’s in demand, or architectural sketches, or K–12 syllabus design.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">To compete, data companies arrange things so that they will always have workers on call while preserving their freedom to drop them at a moment’s notice. “Every vendor is going to have some kind of setup whereby they don’t really make promises to people,” says a senior employee of a major data company. The companies rarely have much notice of these shifts themselves, sometimes because the AI developers aren’t sure exactly what data they need in the first place, other times because they are shopping around for the best deal. “They want to keep us in the dark,” the employee continues, “so we inevitably keep the contributors in the dark, then a purchase falls through and you have a thousand people you’ve trained and formed a relationship with just saying, like, ‘What the fuck? Why isn’t there work?’ It’s a horrible feeling from an operator’s perspective, too, but obviously it’s way worse for them.”</p>
<figure class="_1nqd5v80">
</figure><p class="duet--article--article-body-component z1fbk00 body-text">The workers at the bottom of this supply chain exist in a state of extreme precarity and maximum competitive frenzy — especially because their strict confidentiality agreements make it impossible for them to establish any kind of seniority or relationship that might outlast a particular project. “The power is all on one side because they can’t talk about it,” says Matthew McMullen, a strategy and operations executive who has worked in the industry since the self-driving-car boom in the mid-2010s. “The labs benefit from you not being able to leverage your experience in the market, and this silence is like their pricing power. The silence is their ability to extract mass information from people without giving them the power to object or to unionize or to make companies themselves. As long as they can’t prove what they’ve done, these raters can’t demand what they’re worth. The only way that people can demand things is by showing their ability to step up, to take on more work. The only power that they have is to keep going, to get back in line.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Which is what they do. When a project for Mercor ends, managers often post a link to other projects on the platform and encourage people to apply. “But again, there are thousands of people applying, so you throw your application into a hole and hope to hear back at some undefined point,” says Katya. While they wait, workers sign up for Handshake, Micro1, Alignerr, or another of the ever-growing number of data providers.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">These companies are always recruiting. Like Mercor, many use AI interviewers and automated evaluations, meaning they have no incentive to limit the number of interviews they do. Mercor offers referral bonuses of several hundred dollars, leading some to promote the company so aggressively that mentions of it have been banned from several subreddits. Katya has applied for dozens of jobs and gotten three, not an unusual ratio.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Nor do companies bear any cost for overhiring. Because workers are ostensibly independent contractors, they are not owed paid time off, breaks, healthcare, overtime pay, or unemployment benefits. It’s free to keep them hanging around, and a surplus of vetted workers ensures they will jump quickly to finish tasks before someone else does. It all combines to create an arrangement in which employers can turn labor on and off like a tap. (Reached for comment, Mercor spokesperson Heidi Hagberg said that “the nature of this is project based contract work, meaning it can extend, pause, or end at any time, especially as the client’s scopes and needs evolve,” and that many of the worker complaints “were centered around the misalignment of expectations of a full-time job versus -project-based work.”)</p>
<p class="duet--article--article-body-component z1fbk00 body-text">If you move fast and get lucky and have the right combination of expertise and stay on the right side of each platform’s unique and mysterious recipe of productivity metrics, you can make decent money. I spoke to a playwright making $10,000 a month, a multitalented chemist who at various points found gigs demonstrating poker and singing for AI. But even then, there is an inescapable awareness of ephemerality because producing training data means working toward your own obsolescence. While the number of people doing data work may continue to rise, any particular gig will last only as long as it takes for the machines to successfully mimic it. It takes years for a human to develop expertise, and sooner or later, they’re going to run out of skills to sell.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">A worker with a master’s in linguistics had found steady rubric work for a year, but late in 2025, he noticed it was becoming more difficult to stump the models. Any obscure theory or Indigenous language he asked about, the model would find the correct papers. Instead of submitting three or four rubrics per week, he was lucky to get one. Everyone else on the project was following the same trajectory, so he wasn’t surprised when it came to an end. Their know-how had been extracted. In the past, he’d always been able to find a new gig, but now when he looked around, he saw only requests for medical experts, human-resources managers, and teachers. He has now been without work for five months and isn’t sure what to do next.</p>
<blockquote class="mal5830">
<div class="mal5831">
<div class="mal5832">These platforms are reminiscent of Uber and Lyft a decade ago. Yet in some ways these workers are in a worse position, more replaceable despite their advanced degrees</div>
</div>
</blockquote>
oTo the extent that policy responses to AI automation are discussed at all, they mostly concern what to do when AI renders large categories of workers obsolete. Maybe this will happen, but another possibility is that particular tasks will get automated and humans redistributed to other parts of the production process, some revising so-so AI output, others crafting rubrics to improve it. Much of this work will be inherently intermittent, which means it will be done by independent contractors, workers whom current regulations leave almost wholly unprotected. Daron Acemoglu, a professor of economics at MIT who studies automation, compares the situation to that of weavers, who before the industrial revolution were “like the labor aristocracy,” self-employed artisans in control of their own time. Then came weaving machines, and in order to survive, they were forced to take new jobs in factories, where they worked longer hours for less money under the close supervision of management. The problem wasn’t simply that technology took their jobs; it enabled a new organization of work that gave all power to the owners of capital, who made work a nightmare until labor organizing and regulation set limits.
<p class="duet--article--article-body-component z1fbk00 body-text">Early labor skirmishes are already happening, mostly in California, which has some of the most aggressive rules around classifying platform workers. Three class-action lawsuits have been filed against Mercor in the past six months. (Similar suits were previously filed against Surge AI and Scale AI, which is settling.) The lawsuits all accuse the companies of misclassifying workers as independent contractors given the “extraordinary control” they exert over them. This is “an entirely new kind of work,” one that the company trains people to do and that cannot be done except on the company’s platform. Workers have so little visibility into what they’re working on that one person, alleges a suit filed in December, accepted a Mercor project only to be tasked with recording himself reading sexually explicit scripts. Once he discovered this, the worker risked deactivation if he abandoned the project, forcing him to “choose between being paid and being humiliated.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">These companies are reminiscent of Uber and Lyft a decade ago, says Glenn Danas, a partner at the law firm Clarkson, which is suing Mercor and several other data platforms. Yet in some ways these workers are in a worse position, more replaceable despite their advanced degrees. Uber drivers have to be physically present in a city to work, and they can organize and push for regulation there. If the same were to happen with data workers, companies could just recruit from somewhere else where people will work for less. When Mercor cut pay for its Meta project to $16 per hour, it dropped below the minimum wage in California and other states, yet people there kept working because they needed the money. This was something at least one supervisor acknowledged, writing in Slack, “While we won’t actively hire from any states where the minimum wage is above the project’s rate, if you are already active on the project and would like to work at the $16/hr rate, we want to enable you to do so.”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Entire professions risk a similar race to the bottom, says Acemoglu, if companies are able to pit workers against one another, each selling their data before someone else can underbid them. “We may also need unionlike organizations that exercise some sort of collective ownership and prevent any kind of simple divide-and-rule strategies by large companies to drive down data prices,” he says. “If there isn’t the legal infrastructure for a data economy of this sort, many of the people who produce the data will be underpaid or, to use a more loaded term, <em>exploited.</em>”</p>
<p class="duet--article--article-body-component z1fbk00 body-text">Katya was among the thousands of people invited to join the $16-an-hour Project Nova and was appalled by the low pay. “I think that was Mercor’s experiment in how close to the bottom they can scrape without jeopardizing the data that they’re getting,” she says. Her main project had been paused for weeks and might resume the next day or never.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">In the end, she decided the money wasn’t worth it. She applied to work at a local coffee shop. It wasn’t the career pivot she’d imagined when she went to grad school; she just hoped working as a barista would be more stable. “At least when you work at a coffee shop for minimum wage, you have some friends to talk to and a boss who pretends to care about you. You have some kind of security; you know what your hours are going to be week to week,” she says.</p>
<p class="duet--article--article-body-component z1fbk00 body-text">But then she heard her phone ding. One of her projects was back on.</p>
</div>
</div>]]></description>
      <link>https://www.theverge.com/cs/features/877388/white-collar-workers-training-ai-mercor</link>
      <guid>https://www.theverge.com/cs/features/877388/white-collar-workers-training-ai-mercor</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Andrew O’Hagan · Stay Classy: Mummy’s Favourite]]></title>
      <description><![CDATA[<p>In the days​ of disco and Aramis 900, when the relationship between entitlement and sleaze could still seem novel, Prince Andrew came across like the more relatable sort of wanker, high on royal privilege but in touch with the inner life of the standard British male. ‘If he wasn’t a member of the royal family,’ the astrologer Russell Grant said, ‘his ideal role would be running a beach bar in the sun – with the odd blue movie being shown at the back.’ Among the prince’s early girlfriends were Koo ‘Starkers’ Stark and Vicki Hodge, an actress whose better-known works include <em class="emphasisClass">The Stud</em> and <em class="emphasisClass">Confessions of a Sex Maniac</em>. Hodge had a colourful line in ex-boyfriends, including John Bindon, an actor-gangster who had holidayed with Princess Margaret and was tried for murder. The days of wine and roses for the pre-hyphenated Windsors left a few stains on the carpet, but the royals still acted as if they were beyond reproach.</p><p>Mummy loved Andrew, and what Mummy loved, Mummy protected. By 1984, it seemed he’d got the basic point about dropping the floozies and finding the sort of woman who would ‘understand him’. Enter ‘Chatterbox One’, the codename given to Sarah Ferguson by air traffic controllers when she was learning to fly, a woman in happy possession of two O-levels who exuded jolliness and scads of suitability. (Her father was Prince Charles’s polo manager and it was Diana who set her up with the fourth-in-line.) After a few country weekends and acres of japes, Ferguson was installed as the Duchess of York.</p>
<p>Along with that ‘love of fun’ admired by the tabloids, Fergie brought a few money problems and a talent for reaching beyond her grasp, though not beyond Andrew’s grasping. As a couple, they have always been too stupid to understand the vulnerability of the institution that supports them, and they began wrecking it from the inside as soon as they met. Years ago, before it was fashionable, some of the youngsters in the family were calling Andrew ‘the Nonce’, and there was general dismay at the Yorks’ reckless avarice. The British royal fantasy has a few sustaining mythologies, and one of them is dignity, a quality defined, after Andy and Fergie, more by its absence. The late queen can be held responsible for much, but nobody could accuse her of seeming to <em class="emphasisClass">enjoy</em> her role. For the Yorks, however, enjoyment was everything, and the notion of royal sacrifice, arguably a red herring in the House of Saxe-Coburg and Gotha, was finally obliterated by their actions. The writing was on the wall, or on the T-shirt, when Sarah Ferguson appeared in the mid-1980s wearing one that said ‘Piste Again’. The duchess loved skiing and being on holiday and Andrew was addicted to having everything for free. What to do? Eventually, Andrew Lownie records, they were lent King Hussein of Jordan’s seven-bedroomed Castlewood House on the edge of Windsor Great Park. ‘Bored, Sarah started 1987 with three weeks at Sandringham, followed by a fortnight skiing in Klosters, and a ten-day break with Andrew in Barbados paid for by the multi-millionaire Robert Sangster.’ At this point, Sangster had been a tax exile for twelve years. Stay classy.</p>
<p>The Yorks charged <em class="emphasisClass">Hello!</em> magazine a quarter of a million quid for pics of their ‘homelife’. They took £126,000 from the <em class="emphasisClass">Daily Express</em> for an interview. She charged £50,000 for her vague involvement in a film, <em class="emphasisClass">Young Victoria</em>, and signed on to start the second leg of the Whitbread Round the World Yacht Race in Montevideo, demanding £38,000 worth of first-class air tickets to get there. While other poor buggers in the family were opening jumble sales in Inverness, Andy and Fergie were sniffing out freebies in the dodgiest corners of the world, as confirmed in Lownie’s remarkable catalogue of half-hidden truths. For Andrew, who served in the British armed forces and was underwritten by British taxpayers, the racking up of personal opportunities and financial favours was treacherous. Among his ‘contacts’ were some of Britain’s enemies and multiple opponents of common decency. It didn’t take long for the braying duo to start cheating on each other, too. Only a few years into their marriage, the duchess became involved with a man called Steve Wyatt, who had ‘extensive commercial interests in the Middle East’. ‘His stepfather was a heavy purchaser of Iraqi crude oil,’ Lownie writes, and was ‘at the time negotiating for Iraqi investment in his own US-based refineries. To help Wyatt and to the consternation of the queen’s private secretary, Robert Fellowes, Sarah hosted a dinner at Buckingham Palace in August 1990, the month Iraq invaded Kuwait, for Dr Ramzi Salman, head of the Iraqi State Oil Marketing Organisation and one of Saddam Hussein’s closest confidants.’</p>
<p>Wholesale corruption takes time, but meanwhile Fergie was trying to make money out of <em class="emphasisClass">Budgie the Little Helicopter</em>, a story she cribbed (she says not) from an earlier aviation-inspired sentimentalist. She was also flogging boxes of royal teabags, Wedgwood plates and ‘quality’ pillowcases. (Her brand of luxury goods was called Duchess Originals in America, a play on Prince Charles’s charity biscuits outfit, Duchy Originals. Imagine how annoying he found that! Plus: cool it with the tea parties. Hadn’t she heard of the American Revolution?) While Andrew was off shaking hands with murderers, Sarah sweated the small stuff, spending time in Qatar in a suite costing £2650 a night, paid for by the emir. In the morning she was talking to <em class="emphasisClass">Hello!</em> and in the afternoon she was claiming £50,000 for giving a boost to Rupert Murdoch’s Foxtel cable network, or advertising soft drinks on American TV for $500,000 (she was the first royal to be paid to endorse a product), or accepting £100,000 from an Austrian building magnate to cut the ribbon in a shopping precinct. Fergie always spoke as if she was the tireless workhorse while Randy Andy was off doing his war hero/playboy thing, lighting up the world with big deals and pathetic gropes. ‘You have to understand what I am dealing with here,’ she told a friend. ‘I’m married to a man who has never been inside a supermarket.’ Well, she more than made up for it. Such pressure on a single mother was not to be sniffed at – and she had a plane to Verbier to catch.</p>
<p>There must be something about private jets and presidential suites that renders you incapable of living any other way. The Yorks wanted never to have to touch down in reality, a condition that only billionaires can plausibly sustain, but Andrew’s skewed understanding of his birthright very quickly made him think it appropriate that he should have oodles of everything in a world without bills. Trouble was, the Yorks couldn’t stop saying yes to the odd thousand quid here and there, because, like many addicts, they loved the hit of the low-rent encounter, the scaggy thrill of amping it up. In time, the Yorks’ privilege would be passed down to their children, sociopathic holidaymakers both of them, behaving as if freebies are the only thing that can make you believe you are loved. The family appetite graduated from chalet life and pukka friends to entire kingdoms – the Emirates, Saudi Arabia, Kazakhstan and China – where opportunities to leverage their royal status were comically abundant. It was all plastic. All sheen. And it took ages for the dodgiest elites in the world to work out that the Yorks were Britain’s most corrupt family and that being close to the queen was their only line of credit.</p>
<p>Thanks to multiple investigations, several court cases and Lownie’s excellent book, their downfall has emerged as an emblematic story of our age. In September 2001, Andrew was given a role as UK special representative for international trade and investment. ‘The appointment came with the support of the queen,’ Lownie writes, ‘and the endorsement of the former trade secretary Peter Mandelson.’ Andrew was a walking category error, perceiving no difference between business and pleasure, between what was good for the country and what was excellent for him, conducting a campaign of international larceny masquerading as public service. Charles thought the job as envoy was a disaster waiting to happen: Andrew was almost certain to disgrace himself in a dramatic way.</p>
<p>Everywhere he went, Andrew was described as rude, arrogant, petulant, shallow, uninformed, unethical, contrary, childish and spoiled. Prince William called him a ‘tosser’, and it’s said, though he denies it, that Prince Harry had a go at punching him out. The Yorks seemed convinced that everybody was just fussing. This attitude could be mistaken for nonchalance, but it’s more like American hustle, devolving to English jollity when the weather turns bad. ‘They were careless people,’ Fitzgerald writes of Daisy and Tom Buchanan in <em class="emphasisClass">The Great Gatsby</em>, ‘they smashed up things and creatures and then retreated back into their money or their vast carelessness, or whatever it was that kept them together, and let other people clean up the mess they had made.’</p>
<p>The Yorks didn’t stay married, divorcing in 1996, but five years or so later she moved back in with him, to the thirty-room Royal Lodge in Windsor Great Park, where the pair lived for years on a cheap lease. With his envoy status as cover and the Exchequer paying for private jets, he spent more than a decade making forays into the world to net even more cash and suck up more privilege and hurt more people, while she got on with pimping him out to corrupt businessmen. (She was caught on camera doing this in 2010, in a sting operation run by the <em class="emphasisClass">News of the World</em>.) When you cover capital crime cases, you notice the ways in which stupidity and evil become indistinguishable. With some criminals, it’s when a low-key, almost flippant toleration of wickedness becomes part of their equipage, as if it makes them feel better about who they really are. Thus, when the Yorks’ daughter Beatrice, who was sixteen, brought a boyfriend, a 23-year-old called Paolo Liuzzo, to their borrowed villa in the South of France, nobody seemed bothered that he had been charged with the manslaughter of a freshman when he was at college. (Shrugs all round.) ‘Liuzzo lent Andrew $10,000,’ Lownie tells us, ‘to pay for removal men to move one of the duke’s girlfriends, Angie Everhart, out of the New York apartment she shared with her then fiancé. Afterwards, Liuzzo said, he “was asked to kneel in the drawing room of their Windsor mansion for a mock knighting ceremony”. Impersonating the queen, the Duchess of York handed him a new nickname: “Sir Fixit”.’ A month after the France trip, she asked him to join them on another holiday in Jamaica. Although the kid sold his story to a paper, the Yorks continued to have him around until the couple broke up. Liuzzo died in 2024, aged 42, from a drug overdose in a Miami hotel. But he left behind a vital image of the family dynamic. ‘Daddy loves Mummy more than Mummy loves Daddy,’ Beatrice told him. ‘But Mummy lives for her title and she loses her title if Daddy remarries.’</p>
<p>Angie Everhart, by the way, Andrew’s ‘girlfriend’, was another actress known for sex films and for posing nude in <em class="emphasisClass">Playboy</em> (she said she was charmed to meet a man who had never put away his own groceries). By this time, his financial and sexual manias were coming together and he was increasingly surrounding himself with the sort of men who shared both interests – and I don’t just mean Jeffrey Epstein. When Andrew was in Bangkok on official business in 2006, staff at the Grand Hyatt Erawan were amazed by the number of women he brought up to his room. Some of the staff spoke to a man from Reuters. It turned out that a mate of Andrew’s, the son of Prince Khalifa bin Salman Al Khalifa of Bahrain, was staying at the Hotel Oriental. Once they learned of this happy coincidence, Lownie’s source tells him, ‘the two princes began sending their favourite girls to each other, as a friendly gesture.’</p>
<p>Andrew found that he liked the company of men who floated above the clouds and above the law. He seems to have volumised his bad behaviour to match theirs, while hoping, in the fetid conditions of the modern Elizabethan court, that if Mummy didn’t think badly of him it didn’t matter. Every time he disgraced himself the queen gave him another honour. He had just been appointed commodore-in-chief of the Fleet Air Arm when, just before the business of passing girls back and forth in Bangkok appeared in the papers, she made him a knight of the Garter, Britain’s oldest, most coveted order of chivalry. In 2008, he took a four-day holiday in Tunisia paid for by the gun smuggler Tarek Kaituni, during which the two men went on what was Andrew’s third visit to Colonel Gaddafi in the span of a few months. Kaituni later gave Beatrice an £18,000 necklace when he attended her 21st birthday party in Marbella. The <em class="emphasisClass">Daily Telegraph</em> reported in 2023 that Sarah’s sixtieth birthday party in 2019 was partly funded by the fraudster Selman Turk, who paid Andrew £750,000 to procure a British passport for a Turkish politician. According to further reports, Andrew claims to have paid the money back.</p>
<p>Who knows what his mother was thinking. A lifetime of conformity, perhaps, had made her susceptible to charming ingrates. In any event, like a Depression-era mother in a James Cagney film, Elizabeth couldn’t see the bad in her boy. The worse he got, the more she wanted to camouflage him with medals, rosettes and ribbons. The irony is that he treated her as badly as he treated every other woman, flogging Sunninghill, the house she gave him as a wedding present, to the son-in-law of the president of Kazakhstan for £3 million over the asking price, despite there being no other bidders, an action that only mired the royal family in more shit when one of the president’s other sons-in-law described the money, according to Lownie, as ‘a sweetener’. To this day, the vendor remains unabashed and unprosecuted, despite having negotiated and accepted what was effectively a personal retainer while serving as a British government envoy. What he gave Kazakhstan in return for this largesse may yet emerge, but let us not forget that the president in question, Nursultan Nazarbayev, was a dictator whose regime tortured opponents and whose security forces opened fire on striking oil workers on 16 December 2011, killing fifteen people and injuring a hundred. Ignoring all that, Andrew tried to introduce these people to his bankers at Coutts. In November 2014, Lownie reports, ‘Andrew was in Saudi Arabia – cost to the taxpayer £43,000 – where the liberal blogger Raif Badawi had had his sentence increased from six hundred to a thousand lashes.’ Accompanied by Beatrice, Andrew ‘stayed on for private time’, attending the Abu Dhabi Grand Prix. It was all very nice apparently and he met up with people he hadn’t seen since his dinner with the bin Ladens. Meanwhile, back on the white-stuccoed ranch in Berkshire, the Duchess of York, with nary a care for the world and its issues, was selling hair straighteners in ‘royal purple’ on QVC.</p>
<p>With the Yorks​ , a whole new set of rules appear in the royal playbook. Chief among them is that one should seek, when explaining a personal fault, to pay oneself such a large compliment that it effectively kills the perception of the fault as being a fault at all. This was initially crucial for the duchess as part of her rehabilitation journey, or what she calls in one of her many books her attempt ‘to rebuild the brand Sarah’. The duchess blamed her ‘over-generous nature’ for her money troubles (in 2010 she had told the ‘fake sheikh’ she could ‘open any door’ to royalty for 500k with a downpayment of 40k). Her ‘fault’ (if it was one) was to give too much to the people in her life and land herself in hot water (silly old me). Andrew tried to pull off the same trick during his <em class="emphasisClass">Newsnight</em> interview with Emily Maitlis in 2019, seeking to explain the reason he’d felt the need to fly to New York and stay with Epstein for three days just to tell him they could no longer be friends. ‘I admit fully that my judgment was probably coloured by my tendency to be too honourable,’ he said, to the disbelief of the entire world.</p>
<p>Virginia Roberts Giuffre couldn’t make it past all the lies and the abuses. That was her reality, that was her fate – to be the daughter of the guy who maintained the air-conditioning units at Mar-a-Lago, where she met Ghislaine Maxwell. At sixteen years old, needing the money and needing the break, she was soon being trafficked for sex with rich and powerful friends of Epstein and Maxwell, another couple who did what they wanted before retreating into their money or their vast carelessness. There are sadnesses in Giuffre’s book that are too deep to rehearse, but all she really wanted was to be among people who had the kinds of freedom she wanted for herself. ‘In contrast to his appearance today,’ she writes in her posthumously published memoir, ‘Prince Andrew then was still relatively fit, with short-cropped brown hair and youthful eyes.’</p>
<blockquote>
<p>He’d long been known as the playboy of the royal family, and as a divorcé … he was holding tight to that role. That night he wore slacks and a light-blue dress shirt, open at the collar, with French cuffs, and elegant cufflinks. When I noticed that Epstein called the prince ‘Andy’, I began to call him that too.</p>
<p>As we chatted in Maxwell’s entryway, I suddenly thought of something: my mom would never forgive me if I met someone as famous as Prince Andrew and didn’t pose for a picture. Excusing myself, I ran to get a Kodak FunSaver from my room, then returned and handed it to Epstein. I remember the prince putting his arm around my waist as Maxwell grinned beside me. Epstein snapped the photo.</p>
</blockquote>
<p class="leftranged">In her memoir she writes that Andrew raped her three times in three different locations. He denies attacking her, but he paid her a reported £12 million to go away. Throughout the process, Giuffre was hounded by the press and eviscerated by those who live with the terrifying delusion that royalty has something to do with virtue. ‘A complete whore’ is the way the victim was described by Lady Victoria Hervey, a socialite who once dated Andrew and later appeared on <em class="emphasisClass">Love Island</em>.</p>
<p>‘I hadn’t wanted to have sex with the prince,’ Giuffre writes, ‘but I felt I had to.’ All the pomp, tradition, ceremony and ‘loyalty’ in the world can’t wash away the simple facts. Maxwell took this young girl to Epstein, who abused her a number of times, then they flew her around the world to be abused by their powerful friends, who lived in a universe of deniability. People who know the former prince say that his main concern, after the <em class="emphasisClass">Newsnight</em> fiasco, was to ensure that his daughters would not be deposed and have to give evidence in support of his lies. (The Pizza Express in Woking will be for ever tattooed on their silent hearts.) A second reason for his ‘falling on his sword’, as they like spuriously to say, was that he wanted to make sure Giuffre didn’t spoil his mother’s platinum jubilee. After the best efforts of lawyers Harbottle &amp; Lewis had failed, and as the plug was being pulled on her favourite son’s charities and his military affiliations and royal patronages, the queen still hoped that he might keep one or two titles, just to cheer him up. Time and Scotland Yard will tell if he can stay out of jail.</p>
<p>With some people, money and sex are the only truths. It’s the ultimate delinquency to believe that gratification itself is power. Bringing down the royal family may be the least terrible consequence of everything Andrew has done. When a lazy aristocrat from a dying dynasty uses a helicopter to travel seventeen miles, the edifice shakes. But when that same man rapes a 17-year-old and calls her a liar, it is the end of days. The gift of Andy and Fergie, which comes at too high a price, has been to bring the antiseptic of daylight to the culture of royal privilege.</p>
<p>These are rough times for the regal character and there may be no way to fix it. ‘The love of virtue, the pursuit of truth, grow stale and dull in the dissipation of a court,’ Hazlitt writes in his essay ‘On the Spirit of Monarchy’. ‘Virtue is thought crabbed and morose, knowledge pedantic, while every sense is pampered, and every folly tolerated … Is it to be wondered at that courts and palaces have produced so many monsters of avarice, cruelty and lust?’</p>
<p>When I contacted Victoria Hervey to confirm that she had called Virginia Giuffre a ‘whore’, she doubled down on the comment. ‘It’s what anyone with a brain knows,’ she told me by email. ‘I think I did call her a druggie hooker. Not sure the exact wording.’ She then recommended a couple of online commentators I might read, including Jay Beecher, a former Ukip activist who was alleged last year by the <em class="emphasisClass">Observer</em> to have been paid £80,000 by someone working for Ghislaine Maxwell’s family to ‘investigate’ Giuffre. Lady Victoria, sister of the 8th Marquess of Bristol, is said by <em class="emphasisClass">Vanity Fair</em> to be a supporter of Reform UK. She admires Donald Trump and collects MAGA hats, telling the magazine that it’s time, this spring, to get one that says ‘Make England Great Again’.</p>]]></description>
      <link>https://www.lrb.co.uk/the-paper/v48/n05/andrew-o-hagan/stay-classy</link>
      <guid>https://www.lrb.co.uk/the-paper/v48/n05/andrew-o-hagan/stay-classy</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Do the Illegible | Ashwin Sundar]]></title>
      <description><![CDATA[<p><time datetime="2025-07-14T16:01:42-06:00">July 14, 2025</time></p><p>Someone revoked my GitHub access at work by accident<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> today, so I decided to catch up on some reading. I read Peter Naur’s 1985 essay <a href="https://pablo.rauzy.name/dev/naur1985programming.pdf">Programming as Theory Building</a>. Published 40 years ago, Naur’s essay feels very relevant today, at a time when software developers struggle to understand their place in an AI-driven world.</p>
<p>While reading the section titled “Program Life, Death, and Revival”, I was struck by the parallels to a book that I have spent the better part of a year reading - <em>Seeing Like a State</em>, by James C. Scott, who was a political science professor at Yale University. The subtitle on the cover reads, “How Certain Schemes to Improve the Human Condition Have Failed”. It’s not the most upbeat read, but it is a fascinating view of the world from the year 1998.</p>
<p><img src="https://ashwinsundar.com/posts/legibility-and-programming/book-and-paper.jpg" alt="Seeing Like a State and Programming as Theory Building" /></p>
<p>Alan Perlis said, “A language that doesn’t affect the way you think about programming, is not worth knowing.”<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. I would extend that to say that a book that doesn’t affect the way you think about the world isn’t worth reading either. <em>Seeing Like a State</em> has affected my world-view by adding the notion of <em>legibility</em> to my thinking.</p>
<blockquote>
<p>Legibility: [The process by which] officials took exceptionally complex, illegible, and local social practices (such as land tenure customs or naming customs) and created a standard grid whereby it could be centrally recorded and monitored.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
</blockquote>
<p>A number of examples of <em>legibility</em> are given throughout the book, including the high-modernist city of Brasilia (designed by a student of modernist architect Le Corbusier), the great collectivization experiment in the former Soviet Union<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>, and compulsory villagization in Tanzania<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup>.</p>
<p><img src="https://ashwinsundar.com/posts/legibility-and-programming/brasilia.jpg" alt="Brasilia versus São Paulo and São Salvador" /></p>
<p>Large institutions prefer that their subjects behave in “legible” ways. Ways which can be observed, monitored - and ultimately taxed and constrained. Another example may be the taming of the American West by the United States government. For one, it meant that politicans could benefit from the highly profitable activities that were occurring far from the nation’s capitol.</p>
<h2 id="programming-as-theory-building">Programming as Theory Building</h2>
<p>Let’s return to software. Peter Naur’s essay describes how the actual physical code generated by the act of programming a computer is insufficient to build a “theory” of the computer program at hand. Using an example of how team B cannot seamlessly adopt team A’s code without (at minimum) a strong exchange of ideas about why the program exists, Naur concludes that:</p>
<blockquote>
<p>…the full program text and additional documentation is insufficient in conveying to even the highly motivated group B the deeper insight into the design, that <strong>theory</strong> which is immediately present to the members of group A.</p>
</blockquote>
<p>In other words, the <em>illegible</em> is what team A’s computer program is really about. The information that only the humans on team A know - about why one architecture was selected over another equally-viable option, about why variables are named the way they are, about why a bootstrapping sequence for the dev and prod servers is configured a certain way - this is where the connection to the real world begins, and is often not explained properly by any amount of documentation and <em>legible</em> works generated by the team. When onboarding to a new team, the time you spend getting “acquainted” with a codebase, learning the team’s idioms, talking to non-technical stakeholders - that’s when you’re learning the <em>illegible</em>.</p>
<p>Naur continues, and defines theory-building as the following:</p>
<blockquote>
<p>Theory Building View: …programming in this sense must be the programmers’ building up knowledge of a certain kind, knowledge taking to be basically the programmers’ immediate possession, any <strong>documentation being an auxiliary, secondary product</strong>.</p>
</blockquote>
<p>In the world of set theory, the <em>Theory of the Program</em> is the set of information that excludes any type of recordable documentation, whether it is code or human-language descriptions of the program. The <em>Theory of the Program</em> is the programmer’s internal model, as it is expressed through their computer code. It’s comparable to a writer sharing their internal world-view through their writing.</p>
<p>As a programmer, how does one determine if they’ve built a sufficient “theory” of their program? Naur lists three things that the programmer with a good theory can do <sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup>:</p>
<blockquote>
<ol><li>Explain how the solution relates to the affairs of the world that it helps to handle…the programmer must be able to explain, for each part of the program text and for each of its overall structural characteristics, what aspect or activity of the world is matched by it.</li>
</ol></blockquote>
<blockquote>
<ol start="2"><li>Explain why each part of the program is what it is, in other words is able to support the actual program text with a justification of some sort.</li>
</ol></blockquote>
<blockquote>
<ol start="3"><li>Respond constructively to any demand for a modification of the program so as to support the affairs of the world in a new manner…the kind of similarity [between the new demand and the operational facilities already built into the program] is one between aspects of the world, [and] only makes sense to the agent who has knowledge of the world.</li>
</ol></blockquote>
<h2 id="the-intersection">The Intersection</h2>
<p>Do you feel uncomfortable yet, with all this talk of implicit knowledge that is only transferable by talking to the original programmers? It’s not your fault, the companies we work for have been serving us Agile-flavored Kool-Aid for decades. It’s all that many of us know, and we think that’s how great software is made!</p>
<p>One goal of a well-oiled software-producing machine is to for the software-producing cogs in their machine to be interchangeable, hot-swappable, bus-factorable. The last thing they want is their developers to internalize theories of their program, because this means the process of software development is now becoming illegible to the company. The company cedes control and power to expensive, work-from-home-demanding, shorts-wearing software developers. The horror!</p>
<p>To solve this pesky problem, the software-producing machines joined forces to develop:</p>
<blockquote>
<p>Programming Methods: A set of <strong>work rules for programmers</strong>, telling what kinds of things programmer should do, in what order, which notations or languages to use, and what kinds of documents to produce at various stages.<sup id="fnref1:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup></p>
</blockquote>
<p>Sound familiar? Remember that this essay was written in 1985, before Agile, and much closer in history to Fred Brooks’ <em>Mythical Man-Month</em>. In my view, Brooks’ <em>Mythical Man-Month</em> takes the opposite stance of Naur’s, that programming is TOO illegible. Brooks ultimately advocates for more companies to turn the act of programming into an engineering discipline.</p>
<h2 id="now-what">Now what?</h2>
<p>Naur concludes his essay<sup id="fnref2:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup>:</p>
<blockquote>
<p>On the Theory Building View the primary result of the programming activity is the theory held by the programmers. Since this theory by its very nature is part of the mental possession of each programmer, it follows that <strong>the notion of the programmer as an easily replaceable component in the program production activity has to be abandoned</strong>. Instead the programmer must be regarded as a <strong>responsible developer</strong> and manager of the activity in which <strong>the computer is a part</strong>. In order to fill this position he or she must be given a permanent position, of a status similar to that of other professionals, such as engineers and lawyers, whose active contributions as employers of enterprises rest on their <strong>intellectual proficiency</strong>.</p>
</blockquote>
<p>In other words, Naur recommends to treat the programmer as a software professional, not a low-agency code-slinger.</p>
<p>And this actually connects nicely to today, to a very modern and relevant phenomenon - the vibe-coding software professional. Where does the activity of vibe-coding fit in to this discussion? Andrej Karpathy, an AI researcher and originator of the term, defines:</p>
<blockquote>
<p>Vibe Coding: Fully give in to the vibes, embrace exponentials, and forget that the code even exists…I just see stuff, say stuff, run stuff, and copy paste stuff, and it mostly works.<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup></p>
</blockquote>
<p>If Naur is right (and I think he is), vibe-coding is <em>precisely the wrong direction</em> we should be going as software professionals! We are ceding all attempts at Theory Building to AI systems, systems owned and trained by the biggest corporations on the planet, hoovering up all our theories of programming and leaving us with stochastic parrots to play slots with, whose inner-workings even the corporations do not understand!</p>
<p>We should not cede control like this to the big corporations. But we also should not sneeze at AI as something to avoid. Let’s use AI to learn more about the systems we’re building, ask better questions, interactively red-team our designs and architectures, and yes even generate code (which we then spend the time to understand and save to our <em>illegible</em> knowledge repositories).</p>
<p>–</p>
<p>The link between Naur, Scott, and the state of software today has been interesting to uncover. I hope to organize my thoughts better and do another dive into this subject. I still need to finish “Seeing Like a State” as well. My GitHub access has since been restored, so it is now time for me to return to being a good cog in the legible system.</p>
<div class="footnotes" role="doc-endnotes"><hr /><ol><li id="fn:1">
<p>Turns out, at <em>{INSTITUTION REDACTED}</em>, you need to submit a PR which adds a person to a secret text file somewhere, in order to modify permissions in GitHub. Multiple people had to approve the PR. Someone had styling-feedback about how the array of names needs to end with a <code>,</code>. But at least it’s legible! <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:2">
<p><a href="https://www.cs.yale.edu/homes/perlis-alan/quotes.html#:~:text=19.%20A%20language%20that%20doesn%27t%20affect%20the%20way%20you%20think%20about%20programming%2C%20is%20not%20worth%20knowing">Perlis, Alan. <em>Epigrams on Programming</em>. Association for Computing Machinery SIGPLAN, 1982.</a> <a href="#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:3">
<p>Scott, James C. Page 2, <em>Seeing Like a State</em>. New Haven and London: Yale University Press, 1998. <a href="#fnref:3" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:4">
<p>Scott, James C. Chapter 6: Soviet Collectivation, Capitalist Dreams, <em>Seeing Like a State</em>. <a href="#fnref:4" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:5">
<p>Scott, James C. Chapter 7: Compulsory Villagization in Tanzania: Aesthetics and Miniaturization, <em>Seeing Like a State</em>. <a href="#fnref:5" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:6">
<p><a href="https://pablo.rauzy.name/dev/naur1985programming.pdf">Naur, Peter. <em>Programming as Theory Building</em>, 1985.</a> <a href="#fnref:6" class="footnote-backref" role="doc-backlink">↩︎</a> <a href="#fnref1:6" class="footnote-backref" role="doc-backlink">↩︎</a> <a href="#fnref2:6" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:7">
<p>Karpathy, Andrej. X/Twitter, 2025. <a href="https://x.com/karpathy/status/1886192184808149383">https://x.com/karpathy/status/1886192184808149383</a> <a href="#fnref:7" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol></div>]]></description>
      <link>https://ashwinsundar.com/posts/legibility-and-programming/</link>
      <guid>https://ashwinsundar.com/posts/legibility-and-programming/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Insurrectionist Brunch: Trumpists plotted to deploy military on U.S. soil]]></title>
      <description><![CDATA[<p><em>This article is a continuation of the <a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/secret-project-2025-plan-to-give-trump-command-of-us-police-21744518/">Big Takeover investigative series</a> begun last year by Cochise Regional News and Phoenix New Times. You can read an expanded version of this story on <a target="_blank" rel="noopener noreferrer" href="https://cochiseregionalnews.substack.com/p/insurrectionist-brunch">CRN</a>. This story is part of the <a href="https://www.phoenixnewtimes.com/news/phoenix-new-times-arizona-watchdog-project-announcement-21754454" target="_blank" rel="noreferrer noopener">Arizona Watchdog Project</a>, a yearlong reporting effort led by New Times and supported by the Trace Foundation, in partnership with Deep South Today.</em></p><p>The Army Navy Country Club is a high-class place.</p><p>The members-only club is located in Arlington, Virginia, five miles from the heart of the nation’s capital. The club bills itself as an exclusive “backyard” to the District of Columbia’s political and military “elite,” boasting a number of former presidents, congressional leaders and military brass among its legacy roster. Its 500 rambling acres of Virginia greenery offer a scene of antebellum pretense, filled with championship golf courses and innumerable tennis courts. There, within sight of the Washington Monument, D.C.’s creme de la creme can luxuriate and unwind in card rooms and at “roof top socials,” or gorge themselves at banquets and brunches.</p><p>Or, they can plot ways to deploy the military on U.S. soil, where troops could be used against Americans.</p><div class="article-related-stories"><p></p><h3>Editor's Picks</h3></div><p>In May 2024, according to documents obtained by Cochise Regional News and Phoenix New Times, the Army Navy Country Club was the backdrop of just such a scheme. As Donald Trump was escalating his campaign to regain the White House, a cadre of figures from Trump’s orbit gathered at the club for a brunch meeting focused on military aspects of Project 2025. Among their ranks were law enforcement personnel and former military and civilian officials from the first Trump administration. Several would go on to work under Trump a second time.</p><p>This brunch was the first attended by the Border Security Workgroup, a little-examined division of the larger Project 2025 effort to plot a course for a second Trump presidency. <a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/secret-project-2025-plan-to-give-trump-command-of-us-police-21744518/">CRN and New Times first reported the workgroup’s existence last year</a>. This workgroup was ostensibly created to generate plans for the implementation of Trump’s promised mass deportations and other national security objectives. But as the brunch’s keynote speaker made clear that day, its mandate was broader and more alarming.</p><p>A round, balding man in his mid-50s, the speaker urged the assembled Trump loyalists, right-wing activists and policymakers to examine workarounds for one of the key protections of the American democratic experiment: the Posse Comitatus Act, which since 1878 has prohibited the use of the military to police Americans on American soil. They’d justify circumventing the law by claiming to secure the nation’s borders amid what Trump and MAGA types portrayed as an invasion of illegal immigrants, terrorists and “transnational criminal organizations.” Their effort was not confined to the border. To this group, the border extended to all 50 states.</p><p><em>Become experts on the Insurrection Act</em>, the speaker counseled. That federal law — which Trump has repeatedly threatened to invoke since retaking office — is the primary exception to Posse Comitatus. It allows the president to seize control of state National Guard units and dispatch both the National Guard and active military forces to American states and cities to quell domestic “insurrections.” According to notes kept by one attendee, the speaker counseled the assembled Project 2025 crowd that the president is both commander in chief of the armed forces and the country’s chief law enforcement official. He said these powers should be “unified for border security.” Provisions of the Insurrection Act held the key to merging those two roles together, in order to “operationalize the capacities of the President’s national powers,” the speaker said.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>Despite the topic, the speaker was neither an expert on border security nor on military law. It was Jeffrey Bossert Clark, a former (and future) Trump official who’d already become infamous for sticking his nose where it didn’t belong.</p><p>An environmental lawyer in the Department of Justice during the first Trump presidency, Clark gained notoriety for enthusiastically working to advance Trump’s efforts to overturn the 2020 election. As a result of that effort, Clark was among the Trump sycophants indicted in Georgia’s Fulton County, along with Trump himself. At the time Clark spoke at the Project 2025 brunch at the Army Navy Country Club in May 2024, that indictment was still active, though it has since been dropped.</p><p>Clark was most likely out of his depth. Yet he’d found the right audience for his expansive theories on Trump’s executive power. These were people with extensive ties to Trump, military professionals supportive of Trump, and the white nationalist and Christian nationalist substrate that undergirded Project 2025. And as is apparent in much of their work product over the next year — which CRN and New Times have acquired — they likely took Clark’s suggestions to heart.</p><p>Over the next several months, the Project 2025 Border Security Workgroup dreamed up a new fusion-center-style law enforcement model that would blend federal, state and local authorities with the military, nationwide. This new structure would theoretically be used to ferret out illegal immigrants and protect Americans against the invading hordes. Documents show the group also contemplated using it for much more.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Clark’s remarks to the Border Security Workgroup that day might be written off as crackpot theories from someone known to be several degrees less than reliable on the subject of what presidents can and cannot do. But his words should be taken seriously.</p><p>For one, Clark has gone on to serve in the second Trump administration as the associate administrator for the Office of Information and Regulatory Affairs, under the White House Office of Management and Budget. And many Border Security Workgroup members — who were among Clark’s brunch audience — have also turned up in positions of federal power. What’s more, Trump has already seized the California National Guard and deployed it on the streets of Los Angeles, along with active-duty Marines, spurring court battles over (you guessed it) Posse Comitatus. Trump has also sabre-rattled about invoking the Insurrection Act seemingly whenever a Democratic-led state or city displeases him.</p><p>These likely aren’t idle threats, documents from the Border Security Workgroup show. Its members spent months working to create plans for Trump that would merge military forces with domestic law enforcement through a new command structure that would ultimately answer directly to Trump. The fact that a man like Jeff Clark was an early source of guidance for those who created these plans does not bode well.</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img height="625" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?w=1024" alt="jeffrey clark speaks at a podium in front of the white house seal" class="wp-image-40650145" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg 5859w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=300,183 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=768,469 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=1024,625 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=1536,937 1536w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=2048,1250 2048w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=1114,680 1114w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=800,488 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=492,300 492w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=400,244 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=550,336 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Getty.jpg?resize=1200,732 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Jeffrey Clark in October 2020.
Yuri Gripas-Pool/Getty Images</figcaption></figure></div>
<p>Without Trump’s lies about the 2020 election, Jeffrey Clark probably doesn’t find himself preaching about circumventing Posse Comitatus at a Project 2025 brunch.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>The three-month period between Trump’s 2020 election loss and Joe Biden’s inauguration was defined by the chaos of election denialism, culminating in the Jan. 6 attack on the U.S. Capitol by Trump supporters. In the weeks following the election, disgraced attorney Sidney Powell unleashed what she called “the Kraken,” a slew of litigation in various courts across the country, seeking to overturn the results of the election. When that fell flat, she and a coterie of Trumpists — including deep-pocketed Trump supporter Patrick Byrne, QAnon fan/former National Security Advisor Michael Flynn and fellow “Kraken” attorney Emily Newman — met with Trump on Dec. 18 to urge him to declare martial law and have the military and National Guard seize voting machines in various states. White House Counsel Pat Cippolone vehemently opposed these recommendations. Trump never implemented them.</p><p>Around the same time as that White House meeting, Attorney General William Barr departed his post as head of the Department of Justice. Barr’s deputy, Jeffrey Rosen, succeeded him. Three days after Rosen’s Christmas Eve appointment as acting attorney general, Trump attempted to enlist him and the DOJ in efforts to overturn the election. “Just say that the election was corrupt, and leave the rest to me and the Republican congressmen,” Trump told him. Rosen declined to accommodate Trump’s wishes.</p><p>Enter Clark, who was then serving as the assistant attorney general for the DOJ’s Environment and Natural Resources Division. Clark had no particular election expertise. His division at the DOJ handles litigation involving the fossil fuel industry and related regulatory issues, and prior to that posting, Clark had a career in the private sector specializing in such matters. Nevertheless, in Clark, Trump had found an ally willing to advance lies about the election.</p><p>The day after Trump pressured Rosen to cast doubt on the election, Clark emailed a draft letter to Rosen for his signature. The letter, addressed to the governor and state legislative leaders of Georgia, falsely stated that the DOJ had “identified significant concerns that may have impacted the outcome of the election in multiple states, including the state of Georgia.” Again, Rosen refused.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Not long after, Clark met with Rosen and advised him that Trump had offered Clark the position of acting attorney general — the gig Rosen had just assumed. Clark had accepted the offer, he told the man he was to supposedly replace. This precipitated an emergency White House meeting between Rosen, DOJ leadership, Trump and his advisors. Confronted with the threat of mass DOJ resignations if he installed Clark as head of the department, Trump backed down. The DOJ never issued statements falsely claiming it found irregularities in the 2020 election.</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img height="525" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?w=1024" alt="a sheriff's office booking photo of jeffrey clark" class="wp-image-40650158" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg 1800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=300,154 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=768,393 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=1024,525 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=1536,787 1536w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=1320,676 1320w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=800,410 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=500,256 500w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=400,205 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=550,282 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Jeffrey-Clark-Mugshot.jpeg?resize=1200,615 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Jeffrey Clark’s booking photo from his indictment in Fulton County, Georgia.
Fulton County Sheriff’s Office</figcaption></figure></div>
<p>How did this man wind up the keynote speaker at a brunch for the assembled “border security” and military wing of Project 2025, to whom he urged the invocation of the Insurrection Act to deploy the military on domestic soil? CRN and New Times sent questions to the White House Office of Management and Budget about Clark’s brunch guidance and involvement with the workgroup. OMB spokesperson Rachel Cauley responded only: “Please use this on record from me: ‘The Phoenix New Times is a communist rag that no one reads.'”</p><p>Following the ignominious end of the first Trump administration, many of Trump’s co-conspirators and their allies found refuge in the world of Project 2025, an effort led by the Heritage Foundation and comprised of several right-wing policy groups. </p><p>Many leading contributors to the project were unabashedly Christian nationalist, and entities of the anti-immigrant network founded by white nationalist John Tanton were among the project’s leading contributors. An examination of groups and the individuals involved in the world of Project 2025 also reveals a deep culture of anti-democratic actors who have long worked to restrict voter access, and/or have taken part in efforts to overthrow elections and undermine election systems. As such, Project 2025 was a synthesis of these pernicious threads of Christian nationalism, white nationalism and those who would seek to seize political power — seemingly at any cost.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>At the time of Clark’s brunch appearance, he was working as a senior fellow and director of litigation at the Center for Renewing America, which was a Project 2025 advisory board member and significant contributor. CRA’s founding president was Russell Vought, a former Heritage official and avowed Christian nationalist who has served as head of the Office of Management and Budget in both Trump administrations. Vought wrote the Executive Office of the President chapter in Project 2025’s infamous 922-page “Mandate for Leadership” policy handbook, giving thanks to Clark for his contributions.</p><p>Others involved in election subversion efforts — including voter restriction activist Cleta Mitchell and former Trump chief of staff Mark Meadows — joined Conservative Partnership Institute, which had been founded by former Heritage leaders, and played a substantial role in Project 2025. CPI is an organization whose website says it works in “incubation” of other right-wing policy groups. It counts among its progeny Vought’s Center for Renewing America and longtime Trump advisor Stephen Miller’s America First Legal Foundation.</p><p>Many members of the Border Security Workgroup had connections to both Trump and such right-wing groups. For example, prior to the Clark brunch, Sheriff Roy Boyd of Goliad County, Texas, had been a panelist at a CPI event held in Coral Gables, Florida. Other speakers at that event included Meadows, Mitchell and Clark’s boss, Russ Vought.</p><p>Boyd and other Project 2025 Border Security Workgroup members — including workgroup leader Leon Rios, a retired Army colonel — also had substantial ties to the Texas Public Policy Foundation. TPPF was a heavy contributor to Project 2025, and during its leadership of this effort, Heritage was headed by former TPPF chief executive Kevin Roberts. Documentation we’ve obtained also shows that TPPF personnel worked directly with the Border Security Workgroup. </p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Like many groups in the Project 2025 sphere, TPPF contained elements related to attempts to overturn the 2020 election. This included Jacki Pick, wife of longtime TPPF director and Evangelical billionaire Doug Deason. According to court documents, Pick — who was an attorney working with the Trump campaign — presented Georgia lawmakers with false evidence claiming to show “suitcases” of fraudulent ballots introduced in Fulton County. At the time, she was a TPPF senior fellow. </p><p>Rios — who served as the overall leader of both the Border Security Workgroup and Project 2025’s Army Work Group, of which the Border Security Workgroup was largely an offshoot — was at the insurrectionist brunch at which Clark spoke. And he took notes.</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img height="630" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?w=1024" alt="marines in tan fatigues stand in front of protesters waving upside down american flags" class="wp-image-40650146" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg 2000w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=300,185 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=768,472 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=1024,630 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=1536,945 1536w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=1106,680 1106w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=800,492 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=488,300 488w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=400,246 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=550,338 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marines-Los-Angeles-Getty.jpg?resize=1200,738 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Protesters demonstrate by U.S. Marines guarding a federal building in June 2025 in Los Angeles.
Mario Tama/Getty Images</figcaption></figure></div>
<p>At the time of the brunch, the Border Security Workgroup was only about a month old. It was still feeling its way — filling out membership, establishing work plans and policy priorities. Documents obtained by CRN and New Times demonstrate that Clark’s guidance that day helped set the tone and trajectory of plans and policies the group would produce for Trump’s Resolute Desk.</p><p>Rios took notes of “key talking points” from Clark’s address and distributed them among workgroup members. According to these notes, Clark spoke of the need for the federal government to “provide protection” to states under threat from “transnational criminal organizations.” In service of this federal “protection” of states, the notes stated, “the President has authority to employ military.”</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>“Recent events have led to the misconception that the military cannot be used at borders due to” Posse Comitatus, Rios wrote — though the former Army colonel mangled it as “possession comitatus.”</p><p>Federal military forces may provide support to civil authorities, and often do in emergencies such as natural disasters. But they are prohibited from acting as enforcers of civilian law. Federal active-duty military and state National Guards have been employed at various times in support roles on the border by state governments and Democratic and Republican presidential administrations. Because state National Guard units are under state and not federal control, they are not generally seen as being subject to the prohibitions of Posse Comitatus. </p><p>But therein lies the rub for supporters of extreme presidential power. Which may be why Clark cited code under the Insurrection Act that would allow Trump to seize control of state National Guard units and deploy them along with active-duty military forces — in a domestic law enforcement capacity — to quell “insurrections.”</p><p>Clark went on to urge the use of capabilities that would merge domestic law enforcement with the military, in Trump’s hands. As such, Clark told the assembled Project 2025 participants that they needed to “become experts” on sections of federal law codified under the Insurrection Act. </p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>For example, Clark told the assembled Project 2025 crowd they needed to bone up on Section 253 of the Insurrection Act, which states that “the President, by using the militia or the armed forces, or both, or by any other means, shall take such measures as he considers necessary to suppress, in a State, any insurrection, domestic violence, unlawful combination, or conspiracy.”</p><p>For an entity called the Border Security Workgroup, these were hardly border security laws.</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img height="113" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?w=1024" alt="Text that reads: &quot;Recent events have led to the misconception that the military cannot be used at borders due to possession comitatus. USC 252 and 253 provides the President with the authority to use military at border. In 1915, military was used to quell Mexican invasion on Texas border. Opinion changed in 1970 due largely to a single legal case. We need to be experts on use 252 and 253.&quot;" class="wp-image-40650154" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png 1200w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=300,33 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=768,84 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=1024,113 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=800,88 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=500,55 500w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=400,44 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Leon-Rios-Border-Security-Workgroup-Notes.png?resize=550,61 550w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">An excerpt from Leon Rios’ notes of the May 2024 brunch.
Records obtained by Cochise Regional News and Phoenix New Times</figcaption></figure></div>
<p>Strangely, according to Rios’ notes, the chief rationale cited by Clark in his attempt to tie such extraordinary actions to border security was the Army’s deployment during the 1915 Bandit War, during which bandits from Mexico attacked towns in Texas. The episode was not an actual declared war, nor was it an instance in which the Insurrection Act was invoked.</p><p>According to documentation obtained by CRN and New Times, Clark’s guidance didn’t sit right with at least one member of the Border Security Workgroup. A few days later, Rios received an email from John Whitley, a veteran who participated in several Project 2025 workgroups and served for a brief period in 2021 as the acting secretary of the U.S. Army.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>“I don’t know if (the Department of Defense) has ever been used for interior enforcement,” Whitley wrote. “I wasn’t sure if the brunch speaker was saying that DoD could or not. I suspect that (National Guard) could be used in a similar role to the border with logistical support and the like.”</p><p>When domestic law enforcement has required help, it’s generally been the National Guard that has provided it in supported roles, Whitley continued. Clark — or “the brunch speaker,” as Whitley labeled him — “may have been saying DoD could be used in other ways, e.g., active duty in a direct interdiction role (e.g., with arrest authority). We could obviously do that if it is legal and the President decides to do it.” But, he added, “I am not sure it would be helpful for a few reasons.”</p><p>Using the military in such a way would be “much more politically contentious and, thus, undermine their support and increase the risk of failure,” Whitley prophetically warned. Military intervention probably wouldn’t help the Department of Homeland Security much, he added, since DHS has Border Patrol and ICE agents to make arrests. Nor would it help the Department of Defense, he wrote, going on to describe the shell game the Pentagon would need to play in order to cycle active, reserve and National Guard components while still meeting the Pentagon’s other foreign deployment obligations.</p><p>CRN and New Times sent questions to Whitley about his participation in the Border Security Workgroup and his thoughts and reservations related to Clark’s guidance and involvement. He has not responded.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>As well-reasoned as Whitley’s reservations may have been, they apparently didn’t move Rios, the workgroup’s leader. A day after Whitley expressed his concerns, Rios sent an email to group members recounting the key points of Clark’s Insurrection Act guidance. He also made an announcement.</p><p>“I have asked Mr. Clark (and/or his colleagues),” Rios wrote, “to participate in the Border Security Work Group.”</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img width="1024" height="683" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?w=1024" alt="christopher miller" class="wp-image-40638119" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=300,200 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=768,512 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=1020,680 1020w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=742,495 742w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=450,300 450w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=400,267 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=550,367 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/01/Christopher-Miller-Getty.jpg?resize=800,534 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Christopher Miller was the acting Secretary of Defense in the last months of Donald Trump’s first presidency.
Tom Williams-Pool/Getty Images</figcaption></figure></div>
<p>The Border Security Workgroup apparently took Clark’s guidance and ran with it. Throughout the rest of the year, its members worked to develop plans to link military forces with all levels of domestic law enforcement.</p><p>Emails show there were more Project 2025 brunches at the Army Navy Country Club, and the group also received continued guidance from Project 2025 leadership and its “DoD leads.” That included Clark. Emails show that Clark was included in Border Security Workgroup correspondence relating to this ongoing guidance and development of hybrid military/domestic law enforcement plans.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>The group also received guidance from “Chris Miller (Project 2025 DoD lead)” at multiple points, according to records. <a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/why-is-arizona-sheriff-shilling-for-private-drone-company-40638111/">Former Trump acting Defense Secretary Christopher Miller</a> wrote the “Mandate for Leadership” chapter on the Department of Defense, in which he called for “true alignment” between the Pentagon and the Department of Homeland Security for “border protection operations” and “defense of critical U.S. infrastructure.” Miller did not respond to inquiries from CRN and New Times.</p><p>Following guidance from “Chris Miller (Project 2025 DoD lead),” the Border Security Workgroup crafted a number of avenues through which active military forces — as well as National Guard units, operating either under the command of willing governors or under imposed federal command — could support law enforcement or serve in a direct law enforcement capacity. </p><p>To be very clear: Documentation shows that the group envisioned these militarized “border security” operations taking place in all 50 states, not just at the border.</p><p>The group’s “main operational effort” was planning for the creation and implementation of a new nationwide “multi-jurisdictional” fusion center-style system of law enforcement. Plans produced by the group by the end of 2024 proposed linking military forces with every level of American domestic law enforcement — local, state, tribal and federal — through the new fusion-center-style command system. This system would be overseen by a “Commander of Domestic Security Operations” appointed by, and answering only to, Trump.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Dubbed “Operation Demonstrate Resolve,” the plan was to be rolled out in phases as the administration pursued its mass immigrant deportation and other national security efforts. (For a deeper exploration of the structure, <a target="_blank" rel="noopener noreferrer" href="https://cochiseregionalnews.substack.com/p/insurrectionist-brunch">see the expanded version of this story on CRN</a>.)</p><p>“Demonstrate Resolve” timelines contained in documents produced by the group bear a striking, though imperfect, resemblance to actions undertaken by the administration throughout the first year of this Trump presidency. A draft policy paper produced by the group toward the end of 2024 recommended plans to facilitate the deployment of up to one million Army soldiers — reserve, active forces and National Guard — on American soil, noting that the president would need to declare an emergency to initiate such a deployment. (Trump <a target="_blank" rel="noopener noreferrer" href="https://www.whitehouse.gov/fact-sheets/2025/01/fact-sheet-president-donald-j-trump-declares-a-national-emergency-at-the-southern-border/">did just that</a> soon after taking office, allowing him to deploy troops at the border, and he has threatened, attempted or executed military deployments to a number of cities.) The group also prepared several draft emergency declarations for Trump. Other Border Security Workgroup documents seem to propose deployment of these military forces to all 50 states over the course of 2025 and 2026, with the initial militarization of the Southwest border serving as “‘pilot’ for future operations.” </p><p>Importantly, as proposed by the group in timelines and other documentation it produced, following initial phases of immigrant detentions and deportations, the new militarized fusion center-style system would persist “in perpetuity thereafter.” It would shift to “sustained operations” so as to mitigate “all threats,” including perceived domestic threats.</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img height="305" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?w=1024" alt="a flow chart showing the organizational structure proposed for &quot;Operation Demonstrate Resolve,&quot; which included military and counterintelligence aspects" class="wp-image-40650152" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png 1200w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=300,89 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=768,228 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=1024,305 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=800,238 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=500,149 500w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=400,119 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Border-Security-Workgroup-Command-Structure-Flow-Chart.png?resize=550,164 550w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">A flow chart of the regional command structure proposed for “Operation Demonstrate Resolve” by the Border Security Workgroup.
Records obtained by Cochise Regional News and Phoenix New Time</figcaption></figure></div>
<p>To be clear: Creation of this new militarized “multi-jurisdictional law enforcement” system would constitute the most substantial reworking of American domestic law enforcement since the Sept. 11 terrorist attacks. The post-9/11 era gave rise to the Department of Homeland Security, our current nationwide network of fusion centers and the Office of the Director of National Intelligence. Like this new proposed system, the post-9/11 system eventually shifted from a mission of “counter-terrorism” to one of “all threats/all hazards” mitigation. In doing so, it has frequently infringed on the civil liberties of Americans engaged in constitutionally protected speech and assembly.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>The Border Security Workgroup also contemplated “counter-intelligence” work to combat an “insider threat” working “to subvert the President’s plan.” Records show the group considered using a variety of means to target a number of different groups, including certain non-governmental organizations, government agencies, judicial districts and a number of states or cities governed by the Democratic Party. They also contemplated targeting college students who were protesting Israel’s actions in Gaza. In a July 2024 email, group member Collin Agee — the “senior Army operations advisor” to the National Geospatial Intelligence Agency, per his LinkedIn — railed against immigrants who, “under the guise of free speech,” protested against Israel’s genocidal war in Gaza.</p><p>“We have entire communities (see Michigan) where the loyalty is to other nations, groups or causes, rather than America and Americans,” Agee wrote.</p><p>Agee did not respond to questions about his views, but Dearborn, Michigan, is known for having one of the largest Muslim immigrant communities in the United States.</p><p>These “counter-intelligence” plans came from the Border Security Workgroup “intelligence team,” which Agee was on. The team was primarily led by retired U.S. Navy Rear Admiral Tony Cothron, who has a long career in military intelligence agencies, including time at the National Security Agency and as the Director of Naval Intelligence. At the time of his involvement with the workgroup, he was the director of national security and intelligence programs at Liberty University, where he was also an associate professor of government. Liberty was founded by televangelist Jerry Falwell Sr., and the evangelical school has long served as an incubator for right-wing and Christian nationalist leadership in the United States.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Core proposals created by Cothron’s team, and related teams, sought the integration of a number of law enforcement, intelligence, military and other government databases — to be data-mined by AI, an undertaking the Trump administration has since pursued. Cothron and his team also proposed the creation of a new “Border Security Intelligence Officer” — “a senior Intel professional (3-star equivalent),” Cothron wrote in a July 2024 email — who would oversee these domestic intelligence operations and report to the “Commander of Domestic Security Operations.”</p><p>That intelligence officer would be “responsible for the counter-intelligence mission,” Cothron added. That mission was described further in a policy paper drafted by the Border Security Workgroup in September 2024. “An insider threat to this strategy can be expected that works with nation-state, transnational and non-governmental entities to subvert the President’s plan,” reads a portion of that paper. It continues: “An active counter-intelligence effort must be organized, integrated across all levels, and actively conducted to identify and prosecute any individuals working for and providing classified or operationally sensitive information on border security plans and activities.” </p><p>Again, plans crafted by the Border Security Workgroup did not end on the border. They were proposed for action in every state and territory of the United States.</p><p>Cothron did not respond to questions from CRN and New Times.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img width="1024" height="671" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?w=1024" alt="tom homan sits next to donald trump at a table" class="wp-image-40015505" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=300,197 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=768,503 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=755,495 755w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=458,300 458w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=400,262 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=550,360 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-30/tom-homan-donald-trump-getty.webp?resize=800,524 800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">President Donald Trump and his chosen border czar, Tom Homan.
Kevin Dietsch-Pool/Getty Images</figcaption></figure></div>
<p>Trump loudly denied any involvement with Project 2025 throughout the 2024 election, and it’s not clear what sort of reception the Trump “team” gave to the plans and proposals crafted by the Border Security Workgroup. But documentation suggests they were given at least some consideration, and that the Trump “team” did share some connective tissue with the Border Security Workgroup.</p><p>Records relating to the May 2024 brunch stated that retired Army Colonel Sergio de la Pena provided guidance to workgroup members at this event, pertaining to expectations of both Project 2025 leadership and “the candidate’s team,” which would “provide insight — guidance — once we get into the swing of the campaign process.” If Trump won, the group anticipated that they would continue to work with the forming administration once the transition process commenced.</p><p>De la Pena had worked in the transition team of the first Trump administration and as Deputy Assistant Secretary of Defense for Western Hemisphere Affairs. Documents show that the workgroup received regular briefings relating to transition efforts throughout 2024, and that de la Pena continued briefing the group on “transition update(s)” into 2025. Records also demonstrate that the Border Security Workgroup was used as a recruitment pool for “transition team” personnel.</p><p>De la Pena did not respond to questions. Asked if the Trump campaign or transition team consulted with or recruited from Project 2025 and its subgroups, White House spokesperson Abigail Jackson did not directly answer. “Only the Fake News media would continue to peddle a bogus narrative that no one — except big time loser Kamala Harris — cared about in 2024 and no one cares about now,” Jackson wrote in an email to CRN and New Times.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Documents also show the group continued its discussion of invoking the Insurrection Act well into September 2024, when it was finalizing plans and proposals for Project 2025 review. This was also a time when the group expected to “receive guidance and input from the Presidential candidate and other key members of the executive team,” seemingly putting the lie to Trump’s frequent and obviously bullshit claims that he had nothing to do with Project 2025.</p><p><a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/tom-homan-spared-phoenix-migrants-now-hes-trumps-darth-vader-22176445/">Tom Homan</a>, who was to be Trump’s “border czar,” was the person the group clearly favored to serve as its proposed “Commander of Domestic Security Operations.” A heavily redacted December 2024 workgroup email, obtained by CRN and New Times, indicates that members of the group likely met with Homan — with their proposals in hand — following the 2024 election.</p><p>In the email, Rios told workgroup members that early that month, he and Boyd — who headed the workgroup team tasked with creating proposals for the militarized fusion center system — had met with an individual (name redacted) to present their plans for the new militarized law enforcement command and discuss the structure of that individual’s “nascent office.” As Rios stated in the email, that “nascent office” would have “the authority to develop, coordinate, and provide oversight for national interagency operations dealing with border security and deportation.” It would likely follow a similar “organizational design” to that of the Office of National Drug Control Policy, which operates under the purview of the White House and is led by an individual colloquially known as the nation’s “drug czar.” Further, Rios wrote, “resourcing options (…) for Border Czar activities are being considered.”</p><p>The email also states that this meeting took place in Fredericksburg, Virginia, where Homan has long maintained a residence, according to Virginia Corporation Commission records. Immediately following this meeting, documents show, the Border Security Workgroup began drafting plans for the “proposed organization” of the “Office of the Border Czar.”</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>CRN and New Times submitted numerous questions to Rios — including about this apparent meeting with Homan, the workgroup’s proposals, guidance it received about the Insurrection Act and involvement with the Trump team. Rios declined to answer these questions, opting only to state that the Border Security Workgroup had “no formal affiliation” with Project 2025 and had “never formally submitted” any materials. When provided with a litany of documentary evidence to the contrary, the retired colonel chose to “stand by” his denials, though he did admit participation in the related Project 2025 Army Work Group. He didn’t respond to further questions.</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large is-resized"><img height="683" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?w=1024" alt="tom homan" class="wp-image-40025578 c4" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp 2048w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=300,200 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=768,512 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=1024,683 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=1536,1024 1536w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=1020,680 1020w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=743,495 743w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=450,300 450w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=400,267 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=550,367 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=800,533 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/ww-media/mediaserver/phx/2025-27/tom-homan.webp?resize=1200,800 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Donald Trump’s border czar, Tom Homan, has cultivated strong ties to anti-democratic extremists.
Gage Skidmore/Flickr/CC BY-SA 2.0</figcaption></figure></div>
<p>Like others in the realm of Project 2025, Homan had cultivated strong ties to anti-democratic extremists tied to efforts to overthrow elections. Specifically, to the America Project.</p><p>The America Project had its roots in the chaotic December 2020 White House meeting in which Michael Flynn, Sidney Powell, Patrick Byrne and Emily Newman urged Trump to seize voting machines. The organization was founded in 2021 by Byrne, Flynn and his brother Joseph. In congressional testimony, Byrne described the America Project as a direct successor to the “Defending the Republic” organization — helmed by Powell and directed by Joseph Flynn, Newman and others — that had pushed the “Kraken” lawsuits. Newman joined America Project as president for a period of time.</p><p>Another attorney on Powell’s “Kraken” cases, Julia Haller, was included on Project 2025 Border Security Workgroup emails pertaining to merging domestic law enforcement with the military, among other aspects of the group’s proposals. During that time, Haller worked as senior counsel at Stephen Miller’s America First Legal Foundation. Haller did not respond to question from CRN and New Times.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>Someone else who hopped on board with the America Project was Homan, who had been ICE director during Trump’s first administration. In 2023, America Project filed a report with the Florida Department of State listing Homan as “director and CEO.” That same year, Homan incorporated multiple entities under the name “Border911,” according to Virginia Corporation Commission records. America Project and Border911 would hold a number of tandem campaign-style events throughout 2023 and 2024 — including at Trump’s Mar-a-Lago resort — with America Project promoting Border911 events as its own. A central theme of these events was “every state is a border state.” The events often combined or conflated issues of border security and election security.</p><p>“Border security” got mere lip service compared to “election integrity,” though. America Project tax records show that while the group did spend tens of thousands of dollars on “border security” causes and often used Homan and Border911 to fill seats at events, it spent <em>millions</em> in relation to efforts to undermine the results of the 2020 presidential election and 2022 midterms.</p><p>That included around $710,000 in “legal support” to attorney Stefanie Lambert of “Kraken” infamy. She is currently awaiting trial in Michigan on charges related to her alleged accessing of voting machines and non-public voter data in several Michigan counties. In 2021, America Project also paid at least $2.75 million to <a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/shady-firm-that-led-arizonas-sham-audit-dissolves-lays-off-its-staff-12774632/">Cyber Ninjas</a>, the firm hired to conduct the lengthy “audit” of Maricopa County votes cast in the 2020 election. America Project also funded We The People AZ Alliance, which worked to undermine results in the 2022 Arizona midterm elections. During this period, the group employed <a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/kari-lake-lawyer-skips-hearing-flips-off-state-bar-arizona-19035387/">now-disgraced attorney Bryan Blehm</a>, who represented both Cyber Ninjas and failed 2022 candidate Kari Lake in her attempts to overturn her election loss to Arizona Gov. Katie Hobbs.</p><p>Homan served as something of a lynchpin among various players in the Project 2025 realm, particularly regarding border security and elections. Tax records show that Homan’s private firm, Homeland Strategic Consulting, was paid at least $480,000 in “media consulting” fees by the Immigration Reform Law Institute, the legal arm of the anti-immigrant network founded by white nationalist John Tanton. (To be very clear, the Tanton network is not anti-<em>illegal</em> immigrant, but fully anti-immigrant.) In 2023, Homan was paid $120,000 as a director of the America Project. That same year, he was listed as a contributor to Project 2025 in his capacity as a Heritage “visiting fellow.” That same year, Homan was also listed as a member of the Texas Public Policy Foundation’s “Border Security Coalition,” a group that included Rios and de la Pena of the Border Security Workgroup.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>In 2024, the FBI <a target="_blank" rel="noopener noreferrer" href="https://www.ms.now/news/tom-homan-cash-contracts-trump-doj-investigation-rcna232568">reportedly recorded Homan</a> accepting $50,000 in cash supposedly for his help in securing contracts from the next Trump administration. Once Trump took office, his Department of Justice reportedly shut down that investigation.</p><p>Homan did not respond to multiple questions from CRN and New Times, including about whether he met with members of the Border Security Workgroup, what he thought of its plans and whether he — as “border czar” — would support invocation of the Insurrection Act in the name of border security. In response to the same questions, White House spokesperson Abigail Jackson wrote that Homan “is an American patriot” who “continues to adhere to federal ethics and conflicts of interests rules.”</p><p>Jackson continued: “As a private citizen and government official, Tom has met with and heard from many different organizations who want to share their opinions — this is standard practice. Meetings have never been considered an endorsement of independent organizations’ ideas.”</p><div class="wp-block-group is-layout-constrained wp-block-group-is-layout-constrained"><figure class="wp-block-image size-large"><img height="626" width="1024" src="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?w=1024" alt="A U.S. Marine stands guard at Los Angeles' Westwood Federal Building complex as demonstrators protest U.S. involvement in the Israel/Iran conflict in front of the facility in June 2025." class="wp-image-40650150" srcset="https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg 2000w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=300,183 300w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=768,470 768w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=1024,626 1024w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=1536,939 1536w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=1112,680 1112w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=800,489 800w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=491,300 491w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=400,245 400w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=550,336 550w, https://www.phoenixnewtimes.com/wp-content/uploads/sites/6/2026/03/Marine-Los-Angeles-Getty.jpg?resize=1200,734 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">A U.S. Marine stands guard at Los Angeles’ Westwood Federal Building complex as demonstrators protest U.S. involvement in the Israel/Iran conflict in front of the facility in June 2025.
Scott Olson/Getty Images</figcaption></figure></div>
<p>Since the president’s inauguration in January 2024, many events have unfolded that bear a striking resemblance to the Border Security Workgroup’s plans. </p><div class="article-related-stories"><p></p><h3>Related</h3></div><p>advertisement</p><p>One workgroup participant was Joseph Humire, who was hired at the Pentagon in June 2025 as “deputy assistant secretary of Defense for homeland defense integration and defense support of civil authorities.” Humire has since been promoted to “deputy assistant secretary of War for Americas security affairs.”</p><p>His initial placement occurred right around the time Trump decided to seize California’s National Guard and deploy them, along with active U.S. Marines, to Los Angeles. Trump has since deployed the National Guard to the District of Columbia and threatened other military deployments — through a number of means, including the Insurrection Act — to Portland, Chicago, New Orleans, Charlotte and Minneapolis. In many cases, court orders have enjoined him from following through.</p><p>Another group participant, Earl Matthews, was confirmed as general counsel at the Department of Defense in July 2025. In this position, Matthews is the top attorney consulted by Defense Secretary Pete Hegseth. Matthews did not respond to questions from CRN and New Times, including about whether he would support invoking the Insurrection Act. </p><p>Jon Feere, who at the time was the “director of investigations” at the anti-immigrant Center for Immigration Studies, also participated in the workgroup. Prior to joining the first Trump presidential campaign and transition team, he had worked at CIS for at least a decade. In his time there, he advocated for draconian measures such as ending birthright citizenship, a cause the current Trump administration has pursued. During the first Trump term, Feere served as chief of staff to multiple directors of Immigration and Customs Enforcement, including Homan. He returned to that role last year before being promoted to “senior advisor” to acting ICE director Todd Lyons.</p><div class="article-related-stories"><p></p><h3>Related</h3></div><div class="advertisement-wrapper-container" data-component-id="GPT2xRectanglesDesktopToweronMobileLabeled"><p>advertisement</p><p>advertisement</p></div><p>Ronald Vitiello — one of Lyons’ predecessors as ICE director, and one of Feere’s bosses in that role — was also a member of the Border Security Workgroup. He is now a “senior advisor” with Customs and Border Protection. That agency oversees the Border Patrol, which is now led by former Texas “border czar” Michael Banks, another workgroup participant. Another member, Jason Killmeyer, replaced Feere as ICE chief of staff late last year. Yet another, David Vandenberg, is now an attorney in the DOJ’s Civil Rights Division, where he is leading several lawsuits seeking access to voter registration records in blue states.</p><p>While many things called for by the Border Security Workgroup have transpired, events that have unfolded during this Trump term have not <em>perfectly</em> mirrored its plans. The Trump administration’s many overreaches have prompted spirited and vociferous pushback. Several states, including California, have successfully blocked Trump’s domestic military ambitions in the courts. Trump’s “surges” of thuggish masked immigration agents to Democratic-led cities — <a target="_blank" rel="noopener noreferrer" href="https://www.phoenixnewtimes.com/news/arizona-senator-block-ice-funding-pretti-killing-40640093/">which have resulted in the shooting deaths of two American citizens</a> — have sparked a backlash that has tanked Republicans’ approval numbers and resulted, at least for now, in a drawdown of those hamfisted deployments.</p><p>But Trump and the true believers and opportunists who surround him in government are nothing if not persistent. They’ve persevered despite adverse court rulings and other impediments. It stands to reason that they’ll continue to grab for as much power as they can before what appears to be an inevitable vivisection in the 2026 midterms.</p><p>This November’s elections loom like a deadline. They could flip power in Washington, empowering Democratic lawmakers intent on reining in Trump. For that same reason, it is difficult to gauge what Trump might attempt in order to retain power, spurred on by the same election-denying sycophants who did his bidding in 2020 — some of the same sycophants who guided the Border Security Workgroup as it crafted plans that could be used to deploy the military against Americans.</p><p>Plans that the Trump administration may still try to put into effect.</p>]]></description>
      <link>https://www.phoenixnewtimes.com/news/trumpists-plotted-deploy-military-on-us-soil-before-election-40650142/</link>
      <guid>https://www.phoenixnewtimes.com/news/trumpists-plotted-deploy-military-on-us-soil-before-election-40650142/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Complete Guide to Building Skills for Claude]]></title>
      <description><![CDATA[The Complete Guide <br />
to Building Skills <br />
for Claude<br />
<br />
Contents<br />
Introduction 	3<br />
Fundamentals 4<br />
Planning and design 	7<br />
Testing and iteration 	14<br />
Distribution and sharing 	18<br />
Patterns and troubleshooting 	21<br />
Resources and references 	28<br />
2<br />
<br />
Introduction<br />
A skill is a set of instructions - packaged as a simple folder - that teaches Claude <br />
how to handle specific tasks or workflows. Skills are one of the most powerful <br />
ways to customize Claude for your specific needs. Instead of re-explaining your <br />
preferences, processes, and domain expertise in every conversation, skills let you <br />
teach Claude once and benefit every time. <br />
Skills are powerful when you have repeatable workflows: generating frontend <br />
designs from specs, conducting research with consistent methodology, creating <br />
documents that follow your team's style guide, or orchestrating multi-step <br />
processes. They work well with Claude's built-in capabilities like code execution <br />
and document creation. For those building MCP integrations, skills add another <br />
powerful layer helping turn raw tool access into reliable, optimized workflows.<br />
This guide covers everything you need to know to build effective skills - from <br />
planning and structure to testing and distribution. Whether you're building a <br />
skill for yourself, your team, or for the community, you'll find practical patterns <br />
and real-world examples throughout. <br />
What you'll learn: <br />
• Technical requirements and best practices for skill structure <br />
• Patterns for standalone skills and MCP-enhanced workflows<br />
• Patterns we've seen work well across different use cases <br />
• How to test, iterate, and distribute your skills <br />
Who this is for: <br />
• Developers who want Claude to follow specific workflows consistently <br />
• Power users who want Claude to follow specific workflows <br />
• Teams looking to standardize how Claude works across their organization <br />
Two Paths Through This Guide <br />
Building standalone skills? Focus on Fundamentals, Planning and Design, and <br />
category 1-2. Enhancing an MCP integration? The "Skills + MCP" section and <br />
category 3 are for you. Both paths share the same technical requirements, but <br />
you choose what's relevant to your use case.<br />
What you'll get out of this guide: By the end, you'll be able to build a functional <br />
skill in a single sitting. Expect about 15-30 minutes to build and test your first <br />
working skill using the skill-creator.<br />
Let's get started.<br />
3<br />
<br />
Chapter 1<br />
Fundamentals<br />
4<br />
<br />
Chapter 1<br />
Fundamentals<br />
What is a skill?<br />
A skill is a folder containing:<br />
• SKILL.md (required): Instructions in Markdown with YAML frontmatter<br />
• scripts/ (optional): Executable code (Python, Bash, etc.)<br />
• references/ (optional): Documentation loaded as needed<br />
• assets/ (optional): Templates, fonts, icons used in output<br />
Core design principles<br />
Progressive Disclosure<br />
Skills use a three-level system:<br />
• First level (YAML frontmatter): Always loaded in Claude's system prompt. <br />
Provides just enough information for Claude to know when each skill should <br />
be used without loading all of it into context.<br />
• Second level (SKILL.md body): Loaded when Claude thinks the skill is <br />
relevant to the current task. Contains the full instructions and guidance.<br />
• Third level (Linked files): Additional files bundled within the skill directory <br />
that Claude can choose to navigate and discover only as needed.<br />
This progressive disclosure minimizes token usage while maintaining <br />
specialized expertise.<br />
Composability<br />
Claude can load multiple skills simultaneously. Your skill should work well <br />
alongside others, not assume it's the only capability available.<br />
Portability<br />
Skills work identically across Claude.ai, Claude Code, and API. Create a skill once <br />
and it works across all surfaces without modification, provided the environment <br />
supports any dependencies the skill requires.<br />
For MCP Builders: Skills + Connectors<br />
?????? Building standalone skills without MCP? Skip to Planning and Design - you can <br />
always return here later.<br />
If you already have a working MCP server, you've done the hard part. Skills are <br />
the knowledge layer on top - capturing the workflows and best practices you <br />
already know, so Claude can apply them consistently.<br />
The kitchen analogy<br />
MCP provides the professional kitchen: access to tools, ingredients, and <br />
equipment.<br />
Skills provide the recipes: step-by-step instructions on how to create something <br />
valuable.<br />
5<br />
<br />
Together, they enable users to accomplish complex tasks without needing to <br />
figure out every step themselves.<br />
How they work together:<br />
MCP (Connectivity)	Skills (Knowledge)<br />
Connects Claude to your service <br />
(Notion, Asana, Linear, etc.)<br />
Teaches Claude how to use your service <br />
effectively<br />
Provides real-time data access and tool <br />
invocation<br />
Captures workflows and best practices<br />
What Claude can do	How Claude should do it<br />
Why this matters for your MCP users<br />
Without skills:<br />
• Users connect your MCP but don't know what to do next <br />
• Support tickets asking "how do I do X with your integration" <br />
• Each conversation starts from scratch<br />
• Inconsistent results because users prompt differently each time<br />
• Users blame your connector when the real issue is workflow guidance<br />
With skills:<br />
• Pre-built workflows activate automatically when needed<br />
• Consistent, reliable tool usage<br />
• Best practices embedded in every interaction<br />
• Lower learning curve for your integration<br />
6<br />
<br />
Chapter 2<br />
Planning and design<br />
7<br />
<br />
Chapter 2<br />
Planning and design<br />
Start with use cases<br />
Before writing any code, identify 2-3 concrete use cases your skill should enable.<br />
Good use case definition:<br />
Use Case: Project Sprint Planning <br />
Trigger: User says "help me plan this sprint" or "create <br />
sprint tasks" <br />
Steps: <br />
1. Fetch current project status from Linear (via MCP) <br />
2. Analyze team velocity and capacity <br />
3. Suggest task prioritization <br />
4. Create tasks in Linear with proper labels and estimates <br />
Result: Fully planned sprint with tasks created<br />
Ask yourself:<br />
• What does a user want to accomplish?<br />
• What multi-step workflows does this require?<br />
• Which tools are needed (built-in or MCP?)<br />
• What domain knowledge or best practices should be embedded?<br />
Common skill use case categories<br />
At Anthropic, we’ve observed three common use cases:<br />
Category 1: Document &amp; Asset Creation<br />
Used for: Creating consistent, high-quality output including documents, <br />
presentations, apps, designs, code, etc.<br />
Real example: frontend-design skill (also see skills for docx, pptx, xlsx, and <br />
ppt)<br />
"Create distinctive, production-grade frontend interfaces with high design <br />
quality. Use when building web components, pages, artifacts, posters, or <br />
applications."<br />
Key techniques:<br />
• Embedded style guides and brand standards<br />
• Template structures for consistent output<br />
• Quality checklists before finalizing<br />
• No external tools required - uses Claude's built-in capabilities<br />
8<br />
<br />
Category 2: Workflow Automation <br />
Used for: Multi-step processes that benefit from consistent methodology, <br />
including coordination across multiple MCP servers.<br />
Real example: skill-creator skill<br />
"Interactive guide for creating new skills. Walks the user through use case <br />
definition, frontmatter generation, instruction writing, and validation."<br />
Key techniques:<br />
• Step-by-step workflow with validation gates<br />
• Templates for common structures<br />
• Built-in review and improvement suggestions<br />
• Iterative refinement loops<br />
Category 3: MCP Enhancement<br />
Used for: Workflow guidance to enhance the tool access an MCP server provides.<br />
Real example: sentry-code-review skill (from Sentry)<br />
"Automatically analyzes and fixes detected bugs in GitHub Pull Requests using <br />
Sentry's error monitoring data via their MCP server."<br />
Key techniques:<br />
• Coordinates multiple MCP calls in sequence<br />
• Embeds domain expertise <br />
• Provides context users would otherwise need to specify<br />
• Error handling for common MCP issues<br />
Define success criteria<br />
How will you know your skill is working?<br />
These are aspirational targets - rough benchmarks rather than precise <br />
thresholds. Aim for rigor but accept that there will be an element of vibes-based <br />
assessment. We are actively developing more robust measurement guidance and <br />
tooling.<br />
Quantitative metrics:<br />
• Skill triggers on 90% of relevant queries<br />
 –How to measure: Run 10-20 test queries that should trigger your skill. Track <br />
how many times it loads automatically vs. requires explicit invocation.<br />
• Completes workflow in X tool calls<br />
 –How to measure: Compare the same task with and without the skill enabled. <br />
Count tool calls and total tokens consumed. <br />
• 0 failed API calls per workflow<br />
 –How to measure: Monitor MCP server logs during test runs. Track retry rates <br />
and error codes.<br />
Qualitative metrics:<br />
• Users don't need to prompt Claude about next steps<br />
 –How to assess: During testing, note how often you need to redirect or clarify. <br />
Ask beta users for feedback. <br />
• Workflows complete without user correction<br />
 –How to assess: Run the same request 3-5 times. Compare outputs for <br />
structural consistency and quality.<br />
• Consistent results across sessions<br />
 –How to assess: Can a new user accomplish the task on first try with minimal <br />
guidance?<br />
9<br />
<br />
Technical requirements<br />
File structure<br />
your-skill-name/<br />
├── SKILL.md              # Required - main skill file<br />
├── scripts/              # Optional - executable code<br />
│   ├── process_data.py # Example<br />
│   └── validate.sh # Example<br />
├── references/           # Optional - documentation<br />
│   ├── api-guide.md # Example<br />
│   └── examples/ # Example<br />
└── assets/              # Optional - templates, etc.<br />
    └── report-template.md # Example<br />
Critical rules<br />
SKILL.md naming:<br />
• Must be exactly SKILL.md (case-sensitive)<br />
• No variations accepted (SKILL.MD, skill.md, etc.)<br />
Skill folder naming:<br />
• Use kebab-case: notion-project-setup ✅<br />
• No spaces: Notion Project Setup ❌<br />
• No underscores: notion_project_setup ❌<br />
• No capitals: NotionProjectSetup ❌<br />
No README.md:<br />
• Don't include README.md inside your skill folder<br />
• All documentation goes in SKILL.md or references/<br />
• Note: when distributing via GitHub, you'll still want a repo-level README for <br />
human users — see Distribution and Sharing.<br />
YAML frontmatter: The most important part<br />
The YAML frontmatter is how Claude decides whether to load your skill. Get this <br />
right.<br />
Minimal required format<br />
---<br />
name: your-skill-name<br />
description: What it does. Use when user asks to [specific <br />
phrases].<br />
---<br />
That's all you need to start.<br />
Field requirements<br />
name (required):<br />
• kebab-case only<br />
• No spaces or capitals<br />
• Should match folder name<br />
description (required):<br />
• MUST include BOTH:<br />
 –What the skill does<br />
 –When to use it (trigger conditions)<br />
• Under 1024 characters<br />
• No XML tags (&lt; or &gt;)<br />
• Include specific tasks users might say<br />
• Mention file types if relevant<br />
10<br />
<br />
license (optional):<br />
• Use if making skill open source<br />
• Common: MIT, Apache-2.0<br />
compatibility (optional)<br />
• 1-500 characters <br />
• Indicates environment requirements: e.g. intended product, required system <br />
packages, network access needs, etc.<br />
metadata (optional): <br />
• Any custom key-value pairs <br />
• Suggested: author, version, mcp-server <br />
• Example: <br />
```yaml <br />
metadata: <br />
 author: ProjectHub <br />
 version: 1.0.0 mcp-server: projecthub <br />
```<br />
Security restrictions<br />
Forbidden in frontmatter:<br />
• XML angle brackets (&lt; &gt;)<br />
• Skills with "claude" or "anthropic" in name (reserved)<br />
Why: Frontmatter appears in Claude's system prompt. Malicious content could <br />
inject instructions.<br />
Writing effective skills<br />
The description field<br />
According to Anthropic's engineering blog: "This metadata...provides just <br />
enough information for Claude to know when each skill should be used without <br />
loading all of it into context." This is the first level of progressive disclosure.<br />
Structure:<br />
[What it does] + [When to use it] + [Key capabilities]<br />
Examples of good descriptions:<br />
# Good - specific and actionable<br />
description: Analyzes Figma design files and generates <br />
developer handoff documentation. Use when user uploads .fig <br />
files, asks for "design specs", "component documentation", or <br />
"design-to-code handoff".<br />
# Good - includes trigger phrases<br />
description: Manages Linear project workflows including sprint <br />
planning, task creation, and status tracking. Use when user <br />
mentions "sprint", "Linear tasks", "project planning", or asks <br />
to "create tickets".<br />
# Good - clear value proposition<br />
description: End-to-end customer onboarding workflow for <br />
PayFlow. Handles account creation, payment setup, and <br />
subscription management. Use when user says "onboard new <br />
customer", "set up subscription", or "create PayFlow account".<br />
11<br />
<br />
Examples of bad descriptions:<br />
# Too vague<br />
description: Helps with projects.<br />
# Missing triggers<br />
description: Creates sophisticated multi-page documentation <br />
systems.<br />
# Too technical, no user triggers<br />
description: Implements the Project entity model with <br />
hierarchical relationships.<br />
Writing the main instructions<br />
After the frontmatter, write the actual instructions in Markdown.<br />
Recommended structure:<br />
Adapt this template for your skill. Replace bracketed sections with your specific <br />
content.<br />
---<br />
name: your-skill<br />
description: [...]<br />
---<br />
# Your Skill Name<br />
## Instructions<br />
### Step 1: [First Major Step]<br />
Clear explanation of what happens.<br />
Example:<br />
```bash<br />
python scripts/fetch_data.py --project-id PROJECT_ID<br />
Expected output: [describe what success looks like]<br />
(Add more steps as needed)<br />
Examples<br />
Example 1: [common scenario]<br />
User says: "Set up a new marketing campaign"<br />
Actions:<br />
1. Fetch existing campaigns via MCP <br />
2. Create new campaign with provided parameters<br />
Result: Campaign created with confirmation link<br />
(Add more examples as needed)<br />
Troubleshooting<br />
Error: [Common error message]<br />
Cause: [Why it happens] <br />
Solution: [How to fix]<br />
(Add more error cases as needed)<br />
12<br />
<br />
Best Practices for Instructions<br />
Be Specific and Actionable<br />
✅ Good:<br />
Run `python scripts/validate.py --input {filename}` to check <br />
data format.<br />
If validation fails, common issues include:<br />
- Missing required fields (add them to the CSV)<br />
- Invalid date formats (use YYYY-MM-DD)<br />
❌ Bad:<br />
Validate the data before proceeding.<br />
Include error handling<br />
## Common Issues<br />
### MCP Connection Failed<br />
If you see "Connection refused":<br />
1. Verify MCP server is running: Check Settings &gt; Extensions<br />
2. Confirm API key is valid<br />
3. Try reconnecting: Settings &gt; Extensions &gt; [Your Service] &gt; <br />
Reconnect<br />
 <br />
Reference bundled resources clearly<br />
Before writing queries, consult `references/api-patterns.md` <br />
for:<br />
- Rate limiting guidance<br />
- Pagination patterns<br />
- Error codes and handling<br />
Use progressive disclosure<br />
Keep SKILL.md focused on core instructions. Move detailed documentation to <br />
`references/` and link to it. (See Core Design Principles for how the three-<br />
level system works.)<br />
13<br />
<br />
Chapter 3<br />
Testing and iteration<br />
14<br />
<br />
Chapter 3<br />
Testing and iteration<br />
Skills can be tested at varying levels of rigor depending on your needs:<br />
• Manual testing in Claude.ai - Run queries directly and observe behavior. Fast <br />
iteration, no setup required.<br />
• Scripted testing in Claude Code - Automate test cases for repeatable <br />
validation across changes.<br />
• Programmatic testing via skills API - Build evaluation suites that run <br />
systematically against defined test sets.<br />
Choose the approach that matches your quality requirements and the visibility <br />
of your skill. A skill used internally by a small team has different testing needs <br />
than one deployed to thousands of enterprise users.<br />
Pro Tip: Iterate on a single task before expanding<br />
We’ve found that the most effective skill creators iterate on a single challenging <br />
task until Claude succeeds, then extract the winning approach into a skill. This <br />
leverages Claude’s in-context learning and provides faster signal than broad <br />
testing. Once you have a working foundation, expand to multiple test cases for <br />
coverage.<br />
Recommended Testing Approach<br />
Based on early experience, effective skills testing typically covers three areas:<br />
1. Triggering tests<br />
Goal: Ensure your skill loads at the right times.<br />
Test cases:<br />
•  ✅ Triggers on obvious tasks<br />
•  ✅ Triggers on paraphrased requests<br />
•  ❌ Doesn't trigger on unrelated topics<br />
Example test suite:<br />
Should trigger:<br />
- "Help me set up a new ProjectHub workspace"<br />
- "I need to create a project in ProjectHub"<br />
- "Initialize a ProjectHub project for Q4 planning"<br />
Should NOT trigger:<br />
- "What's the weather in San Francisco?"<br />
- "Help me write Python code"<br />
- "Create a spreadsheet" (unless ProjectHub skill handles <br />
sheets)<br />
15<br />
<br />
2. Functional tests<br />
Goal: Verify the skill produces correct outputs.<br />
Test cases:<br />
• Valid outputs generated<br />
• API calls succeed<br />
• Error handling works<br />
• Edge cases covered<br />
Example:<br />
Test: Create project with 5 tasks<br />
Given: Project name "Q4 Planning", 5 task descriptions<br />
When: Skill executes workflow<br />
Then: <br />
  - Project created in ProjectHub<br />
  - 5 tasks created with correct properties<br />
  - All tasks linked to project<br />
  - No API errors<br />
3. Performance comparison<br />
Goal: Prove the skill improves results vs. baseline.<br />
Use the metrics from Define Success Criteria. Here's what a comparison might <br />
look like.<br />
Baseline comparison:<br />
Without skill:<br />
- User provides instructions each time<br />
- 15 back-and-forth messages<br />
- 3 failed API calls requiring retry<br />
- 12,000 tokens consumed<br />
With skill:<br />
- Automatic workflow execution<br />
- 2 clarifying questions only<br />
- 0 failed API calls<br />
- 6,000 tokens consumed<br />
Using the skill-creator skill<br />
The skill-creator skill - available in Claude.ai via plugin directory or <br />
download for Claude Code - can help you build and iterate on skills. If you <br />
have an MCP server and know your top 2–3 workflows, you can build and test a <br />
functional skill in a single sitting - often in 15–30 minutes.<br />
Creating skills: <br />
• Generate skills from natural language descriptions <br />
• Produce properly formatted SKILL.md with frontmatter <br />
• Suggest trigger phrases and structure <br />
Reviewing skills: <br />
• Flag common issues (vague descriptions, missing triggers, structural <br />
problems) <br />
• Identify potential over/under-triggering risks <br />
• Suggest test cases based on the skill's stated purpose <br />
Iterative improvement: <br />
• After using your skill and encountering edge cases or failures, bring those <br />
examples back to skill-creator <br />
• Example: "Use the issues &amp; solution identified in this chat to improve how the <br />
skill handles [specific edge case]" <br />
 <br />
 <br />
 <br />
 	16<br />
<br />
To use:<br />
"Use the skill-creator skill to help me build a skill for <br />
[your use case]"<br />
Note: skill-creator helps you design and refine skills but does not execute <br />
automated test suites or produce quantitative evaluation results.<br />
Iteration based on feedback<br />
Skills are living documents. Plan to iterate based on:<br />
Undertriggering signals:<br />
• Skill doesn't load when it should<br />
• Users manually enabling it<br />
• Support questions about when to use it<br />
Solution: Add more detail and nuance to the description - this may include <br />
keywords particularly for technical terms<br />
Overtriggering signals:<br />
• Skill loads for irrelevant queries<br />
• Users disabling it<br />
• Confusion about purpose<br />
Solution: Add negative triggers, be more specific<br />
Execution issues:<br />
• Inconsistent results<br />
• API call failures<br />
• User corrections needed<br />
Solution: Improve instructions, add error handling<br />
17<br />
<br />
Chapter 4<br />
Distribution and <br />
sharing<br />
18<br />
<br />
Chapter 4<br />
Distribution and sharing<br />
Skills make your MCP integration more complete. As users compare connectors, <br />
those with skills offer a faster path to value, giving you an edge over MCP-only <br />
alternatives.<br />
Current distribution model (January 2026)<br />
How individual users get skills:<br />
1. Download the skill folder <br />
2. Zip the folder (if needed)<br />
3. Upload to Claude.ai via Settings &gt; Capabilities &gt; Skills<br />
4. Or place in Claude Code skills directory<br />
Organization-level skills:<br />
• Admins can deploy skills workspace-wide (shipped December 18, 2025)<br />
• Automatic updates<br />
• Centralized management<br />
An open standard<br />
We've published Agent Skills as an open standard. Like MCP, we believe skills <br />
should be portable across tools and platforms - the same skill should work <br />
whether you're using Claude or other AI platforms. That said, some skills are <br />
designed to take full advantage of a specific platform's capabilities; authors can <br />
note this in the skill's compatibility field. We've been collaborating with <br />
members of the ecosystem on the standard, and we're excited by early adoption.<br />
Using skills via API <br />
For programmatic use cases - such as building applications, agents, or automated <br />
workflows that leverage skills - the API provides direct control over skill <br />
management and execution. <br />
Key capabilities: <br />
•  `/v1/skills` endpoint for listing and managing skills <br />
• Add skills to Messages API requests via the `container.skills` parameter <br />
• Version control and management through the Claude Console <br />
• Works with the Claude Agent SDK for building custom agents <br />
When to use skills via the API vs. Claude.ai: <br />
Use Case	Best Surface<br />
End users interacting with skills directly Claude.ai / Claude Code<br />
Manual testing and iteration during development Claude.ai / Claude Code<br />
Individual, ad-hoc workflows	Claude.ai / Claude Code<br />
Applications using skills programmatically API<br />
Production deployments at scale	API<br />
Automated pipelines and agent systems	API<br />
19<br />
<br />
Note: Skills in the API require the Code Execution Tool beta, which provides the <br />
secure environment skills need to run. <br />
For implementation details, see: <br />
• Skills API Quickstart<br />
• Create Custom skills<br />
• Skills in the Agent SDK<br />
Recommended approach today<br />
Start by hosting your skill on GitHub with a public repo, clear README (for <br />
human visitors — this is separate from your skill folder, which should not contain <br />
a README.md), and example usage with screenshots. Then add a section <br />
to your MCP documentation that links to the skill, explains why using both <br />
together is valuable, and provides a quick-start guide.<br />
1. Host on GitHub<br />
 –Public repo for open-source skills<br />
 –Clear README with installation instructions<br />
 –Example usage and screenshots<br />
2. Document in Your MCP Repo<br />
 –Link to skills from MCP documentation<br />
 –Explain the value of using both together<br />
 –Provide quick-start guide<br />
3. Create an Installation Guide<br />
## Installing the [Your Service] skill<br />
1. Download the skill:<br />
   - Clone repo: `git clone https://github.com/yourcompany/  <br />
     skills`<br />
   - Or download ZIP from Releases <br />
2. Install in Claude:<br />
   - Open Claude.ai &gt; Settings &gt; skills<br />
   - Click "Upload skill"<br />
   - Select the skill folder (zipped)<br />
3. Enable the skill:<br />
   - Toggle on the [Your Service] skill<br />
   - Ensure your MCP server is connected<br />
4. Test:<br />
   - Ask Claude: "Set up a new project in [Your Service]"<br />
Positioning your skill<br />
How you describe your skill determines whether users understand its value and <br />
actually try it. When writing about your skill—in your README, documentation, <br />
or marketing - keep these principles in mind.<br />
Focus on outcomes, not features:<br />
✅ Good:<br />
"The ProjectHub skill enables teams to set up complete project <br />
workspaces in seconds — including pages, databases, and <br />
templates — instead of spending 30 minutes on manual setup."<br />
❌ Bad:<br />
"The ProjectHub skill is a folder containing YAML frontmatter <br />
and Markdown instructions that calls our MCP server tools."<br />
Highlight the MCP + skills story:<br />
"Our MCP server gives Claude access to your Linear projects. <br />
Our skills teach Claude your team's sprint planning workflow. <br />
Together, they enable AI-powered project management."<br />
20<br />
<br />
Chapter 5<br />
Patterns and <br />
troubleshooting<br />
21<br />
<br />
Chapter 5<br />
Patterns and troubleshooting<br />
These patterns emerged from skills created by early adopters and internal teams. <br />
They represent common approaches we've seen work well, not prescriptive <br />
templates. <br />
Choosing your approach: Problem-first vs. tool-first <br />
Think of it like Home Depot. You might walk in with a problem - "I need to fix a <br />
kitchen cabinet" - and an employee points you to the right tools. Or you might <br />
pick out a new drill and ask how to use it for your specific job. <br />
Skills work the same way: <br />
• Problem-first: "I need to set up a project workspace" → Your skill orchestrates <br />
the right MCP calls in the right sequence. Users describe outcomes; the skill <br />
handles the tools.<br />
• Tool-first: "I have Notion MCP connected" → Your skill teaches Claude the <br />
optimal workflows and best practices. Users have access; the skill provides <br />
expertise. <br />
Most skills lean one direction. Knowing which framing fits your use case helps <br />
you choose the right pattern below.<br />
Pattern 1: Sequential workflow orchestration<br />
Use when: Your users need multi-step processes in a specific order.<br />
Example structure:<br />
## Workflow: Onboard New Customer<br />
### Step 1: Create Account<br />
Call MCP tool: `create_customer`<br />
Parameters: name, email, company<br />
### Step 2: Setup Payment<br />
Call MCP tool: `setup_payment_method`<br />
Wait for: payment method verification<br />
### Step 3: Create Subscription<br />
Call MCP tool: `create_subscription`<br />
Parameters: plan_id, customer_id (from Step 1)<br />
### Step 4: Send Welcome Email<br />
Call MCP tool: `send_email`<br />
Template: welcome_email_template<br />
Key techniques:<br />
• Explicit step ordering<br />
• Dependencies between steps<br />
• Validation at each stage<br />
• Rollback instructions for failures<br />
22<br />
<br />
Pattern 2: Multi-MCP coordination<br />
Use when: Workflows span multiple services.<br />
Example: Design-to-development handoff<br />
### Phase 1: Design Export (Figma MCP)<br />
1. Export design assets from Figma<br />
2. Generate design specifications<br />
3. Create asset manifest<br />
### Phase 2: Asset Storage (Drive MCP)<br />
1. Create project folder in Drive<br />
2. Upload all assets<br />
3. Generate shareable links<br />
### Phase 3: Task Creation (Linear MCP)<br />
1. Create development tasks<br />
2. Attach asset links to tasks<br />
3. Assign to engineering team<br />
### Phase 4: Notification (Slack MCP)<br />
1. Post handoff summary to #engineering<br />
2. Include asset links and task references<br />
Key techniques:<br />
• Clear phase separation<br />
• Data passing between MCPs<br />
• Validation before moving to next phase<br />
• Centralized error handling<br />
Pattern 3: Iterative refinement<br />
Use when: Output quality improves with iteration.<br />
Example: Report generation<br />
## Iterative Report Creation<br />
### Initial Draft<br />
1. Fetch data via MCP<br />
2. Generate first draft report<br />
3. Save to temporary file<br />
### Quality Check<br />
1. Run validation script: `scripts/check_report.py`<br />
2. Identify issues:<br />
   - Missing sections<br />
   - Inconsistent formatting<br />
   - Data validation errors<br />
### Refinement Loop<br />
1. Address each identified issue<br />
2. Regenerate affected sections<br />
3. Re-validate<br />
4. Repeat until quality threshold met<br />
### Finalization<br />
1. Apply final formatting<br />
2. Generate summary<br />
3. Save final version<br />
Key techniques:<br />
• Explicit quality criteria<br />
• Iterative improvement<br />
• Validation scripts<br />
• Know when to stop iterating<br />
23<br />
<br />
Pattern 4: Context-aware tool selection<br />
Use when: Same outcome, different tools depending on context.<br />
Example: File storage<br />
## Smart File Storage<br />
### Decision Tree<br />
1. Check file type and size<br />
2. Determine best storage location:<br />
   - Large files (&gt;10MB): Use cloud storage MCP<br />
   - Collaborative docs: Use Notion/Docs MCP<br />
   - Code files: Use GitHub MCP<br />
   - Temporary files: Use local storage<br />
### Execute Storage<br />
Based on decision:<br />
- Call appropriate MCP tool<br />
- Apply service-specific metadata<br />
- Generate access link<br />
### Provide Context to User<br />
Explain why that storage was chosen<br />
Key techniques:<br />
• Clear decision criteria<br />
• Fallback options<br />
• Transparency about choices<br />
Pattern 5: Domain-specific intelligence<br />
Use when: Your skill adds specialized knowledge beyond tool access.<br />
Example: Financial compliance<br />
## Payment Processing with Compliance<br />
### Before Processing (Compliance Check)<br />
1. Fetch transaction details via MCP<br />
2. Apply compliance rules:<br />
   - Check sanctions lists<br />
   - Verify jurisdiction allowances  <br />
   - Assess risk level<br />
3. Document compliance decision<br />
### Processing<br />
IF compliance passed:<br />
  - Call payment processing MCP tool<br />
  - Apply appropriate fraud checks<br />
  - Process transaction<br />
ELSE:<br />
  - Flag for review<br />
  - Create compliance case<br />
### Audit Trail<br />
- Log all compliance checks<br />
- Record processing decisions<br />
- Generate audit report<br />
Key techniques:<br />
• Domain expertise embedded in logic<br />
• Compliance before action<br />
• Comprehensive documentation<br />
• Clear governance<br />
24<br />
<br />
Troubleshooting<br />
Skill won't upload<br />
Error: "Could not find SKILL.md in uploaded folder"<br />
Cause: File not named exactly SKILL.md<br />
Solution:<br />
• Rename to SKILL.md (case-sensitive)<br />
• Verify with: ls -la should show SKILL.md<br />
Error: "Invalid frontmatter"<br />
Cause: YAML formatting issue<br />
Common mistakes:<br />
# Wrong - missing delimiters<br />
name: my-skill<br />
description: Does things<br />
# Wrong - unclosed quotes<br />
name: my-skill<br />
description: "Does things<br />
# Correct<br />
---<br />
name: my-skill<br />
description: Does things<br />
---<br />
Error: "Invalid skill name"<br />
Cause: Name has spaces or capitals<br />
# Wrong<br />
name: My Cool Skill<br />
# Correct  <br />
name: my-cool-skill<br />
Skill doesn't trigger<br />
Symptom: Skill never loads automatically<br />
Fix:<br />
Revise your description field. See The Description Field for good/bad examples. <br />
Quick checklist:<br />
• Is it too generic? ("Helps with projects" won't work)<br />
• Does it include trigger phrases users would actually say?<br />
• Does it mention relevant file types if applicable?<br />
Debugging approach:<br />
Ask Claude: "When would you use the [skill name] skill?" Claude will quote the <br />
description back. Adjust based on what's missing.<br />
Skill triggers too often<br />
Symptom: Skill loads for unrelated queries<br />
Solutions:<br />
1. Add negative triggers<br />
description: Advanced data analysis for CSV files. Use for <br />
statistical modeling, regression, clustering. Do NOT use for <br />
simple data exploration (use data-viz skill instead).<br />
25<br />
<br />
2. Be more specific<br />
# Too broad<br />
description: Processes documents<br />
# More specific<br />
description: Processes PDF legal documents for contract review<br />
3. Clarify scope<br />
description: PayFlow payment processing for e-commerce. Use <br />
specifically for online payment workflows, not for general <br />
financial queries.<br />
MCP connection issues<br />
Symptom: Skill loads but MCP calls fail<br />
Checklist:<br />
1. Verify MCP server is connected<br />
 –Claude.ai: Settings &gt; Extensions &gt; [Your Service]<br />
 –Should show "Connected" status<br />
2. Check authentication<br />
 –API keys valid and not expired<br />
 –Proper permissions/scopes granted<br />
 –OAuth tokens refreshed<br />
3. Test MCP independently<br />
 –Ask Claude to call MCP directly (without skill)<br />
 –"Use [Service] MCP to fetch my projects"<br />
 –If this fails, issue is MCP not skill<br />
4. Verify tool names<br />
 –Skill references correct MCP tool names<br />
 –Check MCP server documentation<br />
 –Tool names are case-sensitive<br />
Instructions not followed<br />
Symptom: Skill loads but Claude doesn't follow instructions<br />
Common causes:<br />
1. Instructions too verbose<br />
 –Keep instructions concise<br />
 –Use bullet points and numbered lists<br />
 –Move detailed reference to separate files<br />
2. Instructions buried<br />
 –Put critical instructions at the top<br />
 –Use ## Important or ## Critical headers<br />
 –Repeat key points if needed<br />
3. Ambiguous language<br />
# Bad<br />
Make sure to validate things properly<br />
# Good<br />
CRITICAL: Before calling create_project, verify:<br />
- Project name is non-empty<br />
- At least one team member assigned<br />
- Start date is not in the past<br />
 Advanced technique: For critical validations, consider bundling a script <br />
that performs the checks programmatically rather than relying on language <br />
instructions. Code is deterministic; language interpretation isn't. See the Office <br />
skills for examples of this pattern.<br />
4. Model "laziness" Add explicit encouragement:<br />
## Performance Notes<br />
- Take your time to do this thoroughly<br />
- Quality is more important than speed<br />
- Do not skip validation steps<br />
Note: Adding this to user prompts is more effective than in SKILL.md<br />
26<br />
<br />
Large context issues<br />
Symptom: Skill seems slow or responses degraded<br />
Causes:<br />
• Skill content too large<br />
• Too many skills enabled simultaneously<br />
• All content loaded instead of progressive disclosure<br />
Solutions:<br />
1. Optimize SKILL.md size<br />
 –Move detailed docs to references/<br />
 –Link to references instead of inline<br />
 –Keep SKILL.md under 5,000 words<br />
2. Reduce enabled skills<br />
 –Evaluate if you have more than 20 - 50 skills enabled simultaneously<br />
 –Recommend selective enablement<br />
 –Consider skill "packs" for related capabilities<br />
27<br />
<br />
Chapter 6<br />
Resources and <br />
references<br />
28<br />
<br />
Chapter 6<br />
Resources and references<br />
If you're building your first skill, start with the Best Practices Guide, then <br />
reference the API docs as needed.<br />
Official Documentation<br />
Anthropic Resources:<br />
• Best Practices Guide<br />
• Skills Documentation<br />
• API Reference<br />
• MCP Documentation<br />
Blog Posts:<br />
• Introducing Agent Skills<br />
• Engineering Blog: Equipping Agents for the Real World<br />
• Skills Explained<br />
• How to Create Skills for Claude<br />
• Building Skills for Claude Code<br />
• Improving Frontend Design through Skills<br />
Example skills<br />
Public skills repository:<br />
• GitHub: anthropics/skills<br />
• Contains Anthropic-created skills you can customize<br />
Tools and Utilities<br />
skill-creator skill:<br />
• Built into Claude.ai and available for Claude Code<br />
• Can generate skills from descriptions<br />
• Reviews and provides recommendations<br />
• Use: "Help me build a skill using skill-creator"<br />
Validation:<br />
• skill-creator can assess your skills<br />
• Ask: "Review this skill and suggest improvements"<br />
Getting Support<br />
For Technical Questions:<br />
• General questions: Community forums at the Claude Developers Discord <br />
For Bug Reports:<br />
• GitHub Issues: anthropics/skills/issues<br />
• Include: Skill name, error message, steps to reproduce<br />
29<br />
<br />
Reference A: Quick <br />
checklist<br />
Use this checklist to validate your skill before and after upload. If you want <br />
a faster start, use the skill-creator skill to generate your first draft, then run <br />
through this list to make sure you haven't missed anything.<br />
Before you start<br />
   Identified 2-3 concrete use cases<br />
   Tools identified (built-in or MCP)<br />
   Reviewed this guide and example skills<br />
   Planned folder structure<br />
During development<br />
   Folder named in kebab-case<br />
   SKILL.md file exists (exact spelling)<br />
   YAML frontmatter has --- delimiters<br />
   name field: kebab-case, no spaces, no capitals<br />
   description includes WHAT and WHEN<br />
   No XML tags (&lt; &gt;) anywhere<br />
   Instructions are clear and actionable<br />
   Error handling included<br />
   Examples provided<br />
   References clearly linked<br />
Before upload<br />
   Tested triggering on obvious tasks<br />
   Tested triggering on paraphrased requests<br />
   Verified doesn't trigger on unrelated topics<br />
   Functional tests pass<br />
   Tool integration works (if applicable)<br />
   Compressed as .zip file<br />
After upload<br />
   Test in real conversations<br />
   Monitor for under/over-triggering<br />
   Collect user feedback<br />
   Iterate on description and instructions<br />
   Update version in metadata<br />
30<br />
<br />
Reference B: YAML <br />
frontmatter<br />
Required fields<br />
---<br />
name: skill-name-in-kebab-case<br />
description: What it does and when to use it. Include specific <br />
trigger phrases.<br />
---<br />
All optional fields<br />
name: skill-name<br />
description: [required description]<br />
license: MIT # Optional: License for open-source<br />
allowed-tools: "Bash(python:*) Bash(npm:*) WebFetch" # Optional: <br />
Restrict tool access<br />
metadata: # Optional: Custom fields<br />
  author: Company Name<br />
  version: 1.0.0<br />
  mcp-server: server-name<br />
  category: productivity<br />
  tags: [project-management, automation]<br />
  documentation: https://example.com/docs<br />
  support: support@example.com<br />
Security notes<br />
Allowed:<br />
• Any standard YAML types (strings, numbers, booleans, lists, objects)<br />
• Custom metadata fields<br />
• Long descriptions (up to 1024 characters)<br />
Forbidden:<br />
• XML angle brackets (&lt; &gt;) - security restriction<br />
• Code execution in YAML (uses safe YAML parsing)<br />
• Skills named with "claude" or "anthropic" prefix (reserved)<br />
31<br />
<br />
Reference C: Complete skill <br />
examples<br />
For full, production-ready skills demonstrating the patterns in this guide: <br />
• Document Skills - PDF, DOCX, PPTX, XLSX creation<br />
• Example Skills - Various workflow patterns<br />
• Partner Skills Directory - View skills from various partners such as Asana, <br />
Atlassian, Canva, Figma, Sentry, Zapier, and more<br />
These repositories stay up-to-date and include additional examples beyond <br />
what's covered here. Clone them, modify them for your use case, and use them as <br />
templates.<br />
32<br />
<br />
claude.ai]]></description>
      <link>https://resources.anthropic.com/hubfs/The-Complete-Guide-to-Building-Skill-for-Claude.pdf</link>
      <guid>https://resources.anthropic.com/hubfs/The-Complete-Guide-to-Building-Skill-for-Claude.pdf</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Insider Trading Is Going to Get People Killed - The Atlantic]]></title>
      <description><![CDATA[<div>
<section class="ArticleBody_root__2gF81" data-event-module="article body" data-flatplan-body="true"><p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Ayatollah Ali Khamenei was not, it’s safe to assume, a devoted Polymarket user. If he had been, the Iranian leader might still be alive. Hours before Khamenei’s compound in Tehran was reduced to rubble last week, an account under the username “magamyman” bet about $20,000 that the supreme leader would no longer be in power by the end of March. Polymarket placed the odds at just 14 percent, netting “magamyman” a profit of more than $120,000.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Everyone knew that an attack might be in the works—some American aircraft carriers had already been deployed to the Middle East weeks ago—but the Iranian government was caught off guard by the timing. Although the ayatollah surely was aware of the risks to his life, he presumably did not know that he would be targeted on this particular Saturday morning. Yet on Polymarket, plenty of warning signs pointed to an impending attack. The day before, 150 users bet at least $1,000 that the United States would strike Iran within the next 24 hours, <a data-event-element="inline link" href="https://www.nytimes.com/2026/03/03/upshot/prediction-markets-iran-strikes.html">according to a <em>New York Times</em> analysis</a>. Until then, few people on the platform were betting that kind of money on an immediate attack.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Maybe all of this sounds eerily familiar. In January, someone on Polymarket made a series of suspiciously well-timed bets right before the U.S. attacked a foreign country and deposed its leader. By the time Nicolás Maduro was extracted from Venezuela and flown to New York, the user had pocketed more than $400,000. Perhaps this trader and the Iran bettors who are now flush with cash simply had the luck of a lifetime—the gambling equivalent of making a half-court shot. Or maybe they knew what was happening ahead of time and flipped it for easy money. We simply do not know.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Polymarket traders swap crypto, not cash, and conceal their identities through the blockchain. Even so, investigations into insider trading are already under way: Last month, Israel charged a military reservist for allegedly using classified information to make unspecified bets on Polymarket.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">The platform forbids illegal activity, which includes insider trading in the U.S. But with a few taps on a smartphone, <a data-event-element="inline link" href="https://www.theatlantic.com/technology/2026/03/central-lie-prediction-markets/686250/">anyone with privileged knowledge</a> can now make a quick buck (or a hundred thousand). Polymarket and other prediction markets—the sanitized, industry-favored term for sites that let you wager on just about anything—have been dogged by accusations of insider trading in markets of all flavors. How did a Polymarket user <a data-event-element="inline link" href="https://futurism.com/future-society/polymarket-half-time-show">know that</a> Lady Gaga, Cardi B, and Ricky Martin would make surprise appearances during the Super Bowl halftime show, but that Drake and Travis Scott wouldn’t? Shady bets on war are even stranger and more disturbing. They risk unleashing an entirely new kind of national-security threat. The U.S. caught a break: The Venezuela and Iran strikes were not thwarted by insider traders whose bets could have prompted swift retaliation. The next time, we may not be so lucky.</p>

<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">The attacks in Venezuela and Iran—like so many military campaigns—were conducted under the guise of secrecy. You don’t swoop in on an adversary when they know you are coming. The Venezuela raid was <a data-event-element="inline link" href="https://www.nbcnews.com/politics/donald-trump/us-venezuela-strike-nicolas-maduro-captured-how-timeline-trump-rcna252041">reportedly</a> so confidential that Pentagon officials did not know about its exact timing until a few hours before President Trump gave the orders.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Any insiders who put money down on impending war may not have thought that they were giving anything away. An anonymous bet that reeks of insider trading is not always easy to spot in the moment. After the suspicious Polymarket bets on the Venezuela raid, the site’s forecast placed the odds that Maduro would be ousted at roughly 10 percent. Even if Maduro and his team had been glued to Polymarket, it’s hard to imagine that such long odds would have compelled him to flee in the middle of the night. And even with so many people betting last Friday on an imminent strike in Iran, Polymarket forecast only a 26 percent chance, at most, of an attack the next day. What’s the signal, and what’s the noise?</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">In both cases, someone adept at parsing prediction markets could have known that something was up. “It’s possible to spot these bets ahead of time,” Rajiv Sethi, a Barnard College economist who studies prediction markets, told me. There are some telltale behaviors that could help distinguish a military contractor betting off a state secret from a college student mindlessly scrolling on his phone after one too many cans of Celsius. Someone who’s using a newly created account to wager a lot of money against the conventional wisdom is probably the former, not the latter. And spotting these kinds of suspicious bettors is only getting easier. The prediction-market boom has created <a data-event-element="inline link" href="https://gizmodo.com/tracking-insider-trading-on-polymarket-is-turning-into-a-business-of-its-own-2000709286">a cottage industry of tools</a> that instantaneously flag potential insider trading—not for legal purposes but so that you, too, can profit off what the select few already know.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Unlike Kalshi, the other big prediction-market platform, Polymarket can be used in the U.S. only through a virtual private network, or VPN. In effect, the site is able to skirt regulations that require tracking the identities of its customers and reporting shady bets to the government. In some ways, insider trading seems to be the whole point: “What’s cool about Polymarket is that it creates this financial incentive for people to go and divulge the information to the market,” Shayne Coplan, the company’s 27-year-old CEO, said in an interview last year. (Polymarket did not respond to a request for comment.)</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Consider if the Islamic Revolutionary Guard Corps had paid the monthly fee for a service that flagged relevant activity on Polymarket two hours before the strike. The supreme leader might not have hosted in-person meetings with his top advisers where they were easy targets for missiles. Perhaps Iran would have launched its own preemptive strikes, targeting military bases across the Middle East. Six American service members have already died from Iran’s drone attacks in the region; the death toll could have been higher if Iran had struck first. In other words, someone’s idea of a get-rich-quick scheme may have ended with a military raid gone horribly awry. (The Department of Defense did not respond to a request for comment.)</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Maybe this all sounds far-fetched, but <a data-event-element="inline link" href="https://www.theatlantic.com/national-security/2025/12/hegseth-signalgate-trump-defense-pentagon/684997/">it shouldn’t</a>. “Any advance notice to an adversary is problematic,” Alex Goldenberg, a fellow at the Rutgers Miller Center who has written about war markets, told me. “And these predictive markets, as they stand, are designed to leak out this information.” In all likelihood, he added, intelligence agencies across the world are already paying attention to Polymarket. Last year, the military’s bulletin for intelligence professionals <a data-event-element="inline link" href="https://mipb.ikn.army.mil/issues/jul-dec-2025/the-market-knows-best/">published an article</a> advocating for the armed forces to integrate data from Polymarket to “more fully anticipate national security threats.” After all, the Pentagon already has some experience with prediction markets. During the War on Terror, DARPA <a data-event-element="inline link" href="https://www.nytimes.com/2003/07/29/us/threats-responses-plans-criticisms-pentagon-prepares-futures-market-terror.html">toyed with creating</a> what it billed the “Policy Analysis Market,” a site that would let anonymous traders bet on world events to forecast terrorist attacks and coups. (Democrats in Congress revolted, and the site was quickly canned.)</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Now every adversary and terrorist group in the world can easily access war markets that are far more advanced than what the DOD ginned up two decades ago. What makes Polymarket’s entrance into warfare so troubling is not just potential insider trading from users like “magamyman.” If governments are eyeing Polymarket for signs of an impending attack, they can also be led astray. A government or another sophisticated actor wouldn’t need to spend much money to massively swing the Polymarket odds on whether a Gulf state will imminently strike Iran—breeding panic and paranoia. More fundamentally, prediction markets risk warping the basic incentives of war, Goldenberg said. He gave the example of a Ukrainian military commander making less than $1,000 a month, who could place bets that go against his own military’s objective. “Maybe you choose to retreat a day early because you can double, triple, or quadruple your money and then send that back to your family,” he said.</p>
<p class="ArticleParagraph_root__4mszW" data-flatplan-paragraph="true">Again, we don’t know for sure whether any of this is happening. That may be the scariest part. As long as Polymarket lets anyone bet on war anonymously, we may never know. Last Saturday, the day of the initial Iran attack, Polymarket <a data-event-element="inline link" href="https://finance.yahoo.com/news/polymarket-breaks-478-million-record-193853484.html?guccounter=1&amp;guce_referrer=aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8&amp;guce_referrer_sig=AQAAAL5W6qNr9ztg4vzXDF35OSqqmGNUTer4kJHs43ZJcFhiAuFLRcFSct80zkPj0kYeHHeANm05MBYUzzsM20O7NsnMdNhm6rR5OPUZLyXG7QP9G2hvo8impZQgpSEJUeCeTvWVlzBebzxfLXsZ5nIjHs1eiS8vlDF6fpahc0ADNNwh">processed</a> a record $478 million in bets, according to one analysis. All the while, Polymarket continues to <a data-event-element="inline link" href="https://www.theatlantic.com/technology/2026/01/america-polymarket-disaster/685662/">wedge itself into the mainstream</a>. Substack recently struck a partnership with Polymarket to incorporate the platform’s forecasts into its newsletters. (“Journalism is better when it’s backed by live markets,” Polymarket posted on X in announcing the deal.) All of this makes the site even more valuable as an intelligence asset, and even more destructive for the rest of us. Polymarket keeps launching more war markets: Will the U.S. strike Iraq? Will Israel strike Beirut? Will Iran strike Cyprus? Somewhere out there, someone likely already knows the answers.</p>
</section></div>
<div class="ArticleWell_root__fueCa" data-event-module="footer">
<div data-event-module="author footer" class="ArticleFooter_authorFooter__5NsdY">
<div class="SectionHeading_root__3GnqT">
<h3 class="SectionHeading_heading__iNkek">About the Author</h3>
</div>
<div class="ArticleBio_root__ua8zj">
<address id="article-writer-0" class="ArticleBio_author__6pDyl" data-event-element="author" data-event-position="1">

<a class="ArticleBio_headshotContainer__Am2nR" href="https://www.theatlantic.com/author/saahil-desai/" data-event-element="image" aria-label="Read more by Saahil Desai"><img alt="" class="Image_root__XxsOp Image_lazy__hYWHV ArticleBio_headshot__6Aykd" src="https://cdn.theatlantic.com/thumbor/inxEBaZeQTaACKUdbaQWCXNznXw=/1137x85:3753x2701/120x120/media/None/IMG_9791_1/original.jpg" width="60" height="60" /></a>

<a href="https://www.theatlantic.com/author/saahil-desai/" data-event-element="author name">Saahil Desai</a></address></div>
<div class="ArticleAuthorFollow_root__Oyvdr"><button class="ArticleAuthorFollow_followButton__0_Sod" aria-haspopup="true" aria-controls=":Rktapllhim:" aria-expanded="false" aria-label="Open Author Newsletter Signup" data-event-verb="followed" data-event-element="follow button">Follow</button></div>
</div>
</div>
<div class="ArticleBio_bioSection__Hef4P ArticleBio_bioSection__Hef4P"><a href="https://www.theatlantic.com/author/saahil-desai/" class="author-link" data-label="https://www.theatlantic.com/author/saahil-desai/" data-action="click author - name">Saahil Desai</a> is a senior editor at <em>The Atlantic</em>.</div>




<div class="ArticleTags_root__zS_pT">
<div class="ArticleTags_tagTitle__WjjAt">Explore More Topics</div>
<div><a href="https://www.theatlantic.com/tag/person/ali-khamenei/">Ali Khamenei</a>, <a href="https://www.theatlantic.com/tag/general/cryptocurrency/">cryptocurrency</a>, <a href="https://www.theatlantic.com/tag/location/iran/">Iran</a>, <a href="https://www.theatlantic.com/tag/general/money/">money</a>, <a href="https://www.theatlantic.com/tag/person/nicolas-maduro/">Nicolás Maduro</a>, <a href="https://www.theatlantic.com/tag/organization/united-states-department-of-defense/">United States Department of Defense</a>, <a href="https://www.theatlantic.com/tag/location/venezuela/">Venezuela</a></div>
</div>]]></description>
      <link>https://www.theatlantic.com/technology/2026/03/polymarket-insider-trading-going-get-people-killed/686283/</link>
      <guid>https://www.theatlantic.com/technology/2026/03/polymarket-insider-trading-going-get-people-killed/686283/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[[no title]]]></title>
      <description><![CDATA[<header><div class="dusk:bg-gray-700 my-4 bg-white py-4 md:my-10 md:py-8 dark:bg-gray-700">
  <div class="mx-auto max-w-2xl px-4 md:px-8 lg:grid lg:max-w-6xl">
    
    
    <p class="text-gray-550 dark:text-gray-250 dusk:text-gray-250 my-3 text-2xl leading-[1.1] md:leading-[1.2]">
      8GB of RAM is a bummer, but this $599 laptop cuts most of the right corners.
    </p>
          
    <div class="relative">
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1440x810.jpeg 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410.jpeg" target="_blank">
              <img width="2560" height="1440" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410.jpeg" class="intro-image" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_7410-1440x810.jpeg 1440w" sizes="(max-width: 2560px) 100vw, 2560px" /></a>
            
          </div>
        </div>
          </div>
    <div>
      <div class="caption font-impact dusk:text-gray-300 mb-4 mt-2 inline-flex flex-row items-stretch gap-1 text-base leading-tight text-gray-400 dark:text-gray-300">
    
    <div class="caption-content">
      I suspect the MacBook Neo will become a common coffee shop companion.
              
          Credit:
          Andrew Cunningham
                  
          </div>
  </div>
    </div>
  </div>
</div>
</header><div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
          <div class="page-anchor-wrapper">
<p>Buying a cheap laptop is easy. You just go to Best Buy or Newegg or Amazon or Walmart or somewhere, you pick the cheapest one (or the most expensive one that fits whatever your budget is), and you buy it. For as little as $200 or $300, you can bring home something new (as in, “new-in-box” not as in, “was released recently”) that will power up and boot Windows or ChromeOS.</p>
<p>Buying a <em>decent</em> cheap laptop, or recommending one to someone else who’s trying to buy one? That’s hard.</p>
<p>For several years I helped maintain <a href="https://www.nytimes.com/wirecutter/reviews/best-laptop-under-500/">Wirecutter’s guide to sub-$500 laptops</a>, and keeping that guide useful and up to date was a nightmare. It’s not that decent options with good-enough specs, keyboards, and screens didn’t exist. But the category is a maze of barely differentiated models, some of them retailer-exclusive. You’d regularly run into laptops that were fine <em>except</em> for a bad screen or a terrible keyboard or miserable battery life—some fatal flaw that couldn’t be overlooked.</p>
<p>When you <em>did</em> find a good one, the irregular patterns of the PC industry meant you could never be sure how quickly it would disappear, or whether it would be replaced with something of equivalent value. More than once, a new pick for that guide vanished in the short interval between when it was tested and selected and when the update to the guide could be published.</p>
<p>When recommending cheap laptops for the people in my own life, I normally ask them when they want it and how much they’d like to spend, and then stay on top of sales, refurbished sites, and eBay until I find the one fleeting deal on a laptop that meets their needs at their price point. This approach does not scale.</p>
                      
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>One reason why I’ve been so curious about Apple’s long-rumored budget MacBook was because it would be really, really nice to have something close to $500 that a person could just go out and <em>buy</em> without having to worry about whether they were getting the right thing (you wouldn’t want to mistake the <a href="https://store.acer.com/en-us/aspire-go-15-laptop-ag15-32p-c0z2">Acer Aspire Go 15 AG15-32P-C0Z2</a> for the <a href="https://www.acer.com/us-en/laptops/aspire/aspire-go-intel/pdp/NX.JJKAA.001">Acer Aspire Go 15 AG15-71P-59PZ</a>, would you??), or whether it would be available at all. Something with Apple’s typical warranty support and network of retail stores behind it. And something that would integrate better with an iPhone than Microsoft and Google’s platforms are able to.</p>
<p>The MacBook Neo definitely has flaws. It’s missing a few things that have been standard on MacBook Airs and Pros for a very long time. Performance is decent, but in many of our tests, it’s the slowest Mac Apple has shipped since the Apple Silicon Mac era began, including the original M1. And a laptop, any laptop, with 8GB of memory in 2026 is eventually going to cause problems for you—it’s a question of <em>when</em>, not <em>if</em>.</p>
<p>But it starts at $599 (or $499, with Apple’s educational discount). That brings it in way under the $1,100 asking price for the latest MacBook Airs, even if you spring for the $699 version with 512GB of storage and Touch ID. I still think anyone who can afford an Air, even <a href="https://www.apple.com/shop/refurbished/mac/macbook-air">an older refurbished model</a>, will be happier in the long term if they buy the Air instead. But like the $349 iPad before it, I don’t think spec sheet deficiencies will be enough to keep the MacBook Neo from being popular with kids, first-time laptop buyers, or anyone with a modest budget and basic needs.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<div class="toc-container border-t-gray-250 mb-5 border-b-4 dark:border-t-gray-600">
  Table of Contents
  </div>
<div class="page-anchor-wrapper">
<h2>A brand-new design</h2>
<figure class="ars-wp-img-shortcode id-2144551 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1440x810.jpeg 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670.jpeg" target="_blank">
              <img width="2560" height="1440" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670.jpeg" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3670-1440x810.jpeg 1440w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a>
            
          </div>
        </div>
          </div>
          <figcaption>
    
    
      The MacBook Neo’s lid. The Apple logo is embossed, without the mirror finish of the Air or Pro.
          </figcaption></figure></div>
  </div>
      <p>For past budget products, Apple has leaned extensively on updating old designs rather than building all-new ones. For many years, <a href="https://arstechnica.com/gadgets/2017/04/review-apples-329-ipad-is-for-people-who-have-never-upgraded-their-tablet/">the cheapest iPad</a> was an <a href="https://arstechnica.com/gadgets/2021/09/2021-329-ipad-review-the-good-enough-ipad-gets-a-little-better/">updated version</a> of the <a href="https://arstechnica.com/gadgets/2013/11/review-apples-ipad-air-is-a-big-tablet-without-all-the-baggage/">2013 iPad Air</a>; over three generations of the <a href="https://arstechnica.com/gadgets/2020/04/iphone-se-review-though-it-be-but-little-it-is-fierce/">iPhone SE</a>, Apple recycled the designs of both <a href="https://arstechnica.com/gadgets/2013/09/review-with-the-iphone-5s-apple-lays-groundwork-for-a-brighter-future/">2013’s iPhone 5S</a> and <a href="https://arstechnica.com/gadgets/2017/09/iphone-8-and-8-plus-review-the-curious-case-of-the-time-traveling-phone/">2017’s iPhone 8</a>.</p>
<p>I thought it very likely that Apple would reuse the design from its 2018–2020 MacBook Air refresh, which it had <a href="https://arstechnica.com/gadgets/2024/03/walmart-resurrects-the-m1-macbook-air-as-an-entry-level-699-laptop/">already been selling through Walmart</a> for $599. But Apple decided to build an all-new MacBook Neo design instead, one that makes it more consistent with the modern Airs and Pros.</p>
<p>Instead of being wedge-shaped, the Neo is a flat, rounded aluminum rectangle when it’s closed, and it has a slightly smaller footprint than the old 13-inch Air. Four color-matched feet keep the bottom of the laptop up off your table or desk. Its 13-inch screen doesn’t have a notch, but it does have rounded corners at the top and square ones at the bottom, mirroring the design of modern MacBook Airs and Pros. Its resolution and pixel density are very close to the old M1 Air (2408×1506 for the Neo, 2560×1600 for the old Air), but it gets slightly brighter. We measured 506 nits at maximum brightness, in line with Apple’s 500 nits estimate, and higher than the M1 Air’s 400 nits.</p>
<p>The Neo comes in four colors that are a bit more noticeable and eye-catching than the ones Apple uses for the MacBook Air. We were sent a yellow (“Citrus”) review unit, though if I were buying one for myself, I’d probably prefer the dark-blue Indigo. Classic MacBook silver and a pale pastel pink (“blush”) are also available. As it does with the iMacs, Apple ships the MacBook Neo with color-matched wallpapers and a special color-matched theme and text highlight color in the Appearance settings, along with the standard nine options that all Macs have.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<figure class="ars-wp-img-shortcode id-2144543 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2100" data-pswp-height="1520" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors.jpeg 2100w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-640x463.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-1024x741.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-768x556.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-1536x1112.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-2048x1482.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-980x709.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-1440x1042.jpeg 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors.jpeg" target="_blank">
              <img width="2100" height="1520" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors.jpeg" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors.jpeg 2100w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-640x463.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-1024x741.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-768x556.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-1536x1112.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-2048x1482.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-980x709.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/macOS-neo-colors-1440x1042.jpeg 1440w" sizes="auto, (max-width: 2100px) 100vw, 2100px" /></a>
            
          </div>
        </div>
          </div>
          <figcaption>
    
    
      The Neo comes with custom color-matched highlight colors.
              
          Credit:
          Andrew Cunningham
                  
          </figcaption></figure></div>
  </div>
      <p>The MacBook Neo’s keyboard uses the same layout as Apple’s other laptops, including the full-height function keys, and has a very similar feel to the Air’s keyboard overall. Apple is using the same scissor-switch mechanism as in the Air here, though the color-matched finish on the keycaps does feel a little different from the typical black keys. If the typing feel is any different from the MacBook Air’s, it’s so minor that I stopped noticing it almost instantly.</p>
<p>The trackpad is a different story. As we covered <a href="https://arstechnica.com/gadgets/2026/03/macbook-neo-hands-on-apple-build-quality-at-a-substantially-lower-price/">in our hands-on piece</a>, this is the first time in a while that Apple has shipped a trackpad with a physical clicking mechanism, rather than using a Force Touch trackpad that uses haptic feedback to simulate clicking. It took a little getting used to the Force Touch trackpad at first, but Apple has been using it in laptops for more than a decade, so now it’s <em>that</em> trackpad that feels normal to me and a physical clicking mechanism that feels strange.</p>
<p>Apple has engineered this trackpad so that you can click anywhere on its surface and it will feel about the same—there’s no stiff hinge at the top as there is in many trackpads. It uses a pair of <a href="https://en.wikipedia.org/wiki/Flexure">flexures</a> that both move in unison to provide a uniform clicky feeling over its entire surface.</p>
<div class="ars-lightbox align-fullwidth my-5">
          <div class="ars-gallery-1-up my-5">
  <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1440x810.jpeg 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661.jpeg" target="_blank" class="cursor-zoom-in">
    <img width="2560" height="1440" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661.jpeg" class="ars-gallery-image" alt="" aria-labelledby="caption-2144546" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3661-1440x810.jpeg 1440w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a>
      
  </div>
  <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content">
              The Neo’s color-matched keyboard has the same layout and key feel as the Air, but without a backlight.
                    
                      Andrew Cunningham
                  
          </div>
  </div>
</div>
      <div class="flex flex-col flex-nowrap gap-5 py-5 md:flex-row">
  <div class="">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2560" data-pswp-height="1441" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-2048x1153.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-980x552.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1440x811.jpeg 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664.jpeg" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="576" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1024x576.jpeg" class="ars-gallery-image" alt="" aria-labelledby="caption-2144547" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-2048x1153.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-980x552.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3664-1440x811.jpeg 1440w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
      
  </div>
    <div class="md:hidden">
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content">
              Touch ID only comes on the more expensive 512GB model of the Neo.
                    
                      Andrew Cunningham
                  
          </div>
  </div>
    </div>
  </div>
  <div class="flex-1">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1440x810.jpeg 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684.jpeg" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="576" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1024x576.jpeg" class="ars-gallery-image" alt="" aria-labelledby="caption-2144549" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3684-1440x810.jpeg 1440w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
      
  </div>
    <div class="md:hidden">
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content">
              MacBook Neo, 14-inch Pro, 15-inch Air, and 16-inch Pro. The design language is similar up and down the lineup.
                    
                      Andrew Cunningham
                  
          </div>
  </div>
    </div>
  </div>
</div>
<div class="hidden md:block">
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content left">
              Touch ID only comes on the more expensive 512GB model of the Neo.
                    
                      Andrew Cunningham
                  
          </div>
  </div>
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content right">
              MacBook Neo, 14-inch Pro, 15-inch Air, and 16-inch Pro. The design language is similar up and down the lineup.
                    
                      Andrew Cunningham
                  
          </div>
  </div>
  </div>
      </div>
<p>Using it feels fine, and it’s just as accurate as other Apple trackpads, though it’s a bit smaller than even the M1 MacBook Air’s trackpad. But I miss the way you can adjust the feel of clicking on a Force Touch trackpad, and (on some models) the amount of noise it makes. I also hadn’t realized that I’d worked Force Touch into my macOS muscle memory until I used a Mac without it for the first time in a while—using it to quickly rename files and folders in the Finder was the big one for me, but <a href="https://support.apple.com/en-us/102309">you may have others</a>.</p>
                  </div>
              
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>That’s a common theme for the MacBook Neo, actually. Apple hasn’t cut anything that feels absolutely essential to the MacBook and macOS experience, but it <em>has</em> scaled back on a whole lot of small frills that had become standard-issue on all other Macs released this decade.</p>
<p>In addition to the physical-click trackpad, the MacBook Neo comes with a non-backlit keyboard, a 1080p webcam without Center Stage support, no Touch ID button on the base model, and no MagSafe charging connector. Its screen doesn’t support the DCI-P3 wide color gamut (though we measure it at about 91 percent of the sRGB gamut, which is pretty good for this price category), or the True Tone feature that adjusts the display’s color temperature to match ambient lighting. There’s no Thunderbolt connectivity.</p>
<p>Apple has shipped MacBooks missing all of these features before. But it’s been a very long time for some of them—I’m fairly sure a backlit keyboard has been a feature in every single MacBook sold in <a href="https://en.wikipedia.org/wiki/MacBook_(2006%E2%80%932012)#Polycarbonate_unibody_(2009%E2%80%932010)">the last 15 years</a>.</p>
<figure class="ars-wp-img-shortcode id-2144550 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1440x810.jpeg 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702.jpeg" target="_blank">
              <img width="2560" height="1440" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702.jpeg" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3702-1440x810.jpeg 1440w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a>
            
          </div>
        </div>
          </div>
          <figcaption>
    
    
      The Neo on top of the 13-inch M1 MacBook Air.
              
          Credit:
          Andrew Cunningham
                  
          </figcaption></figure></div>
  </div>
      <p>The 1080p webcam and the laptop’s side-firing stereo speakers are unexceptional but functional, though generally I’d say they’re a notch or two better than what you’d get in a PC for this price. The webcam is missing the Center Stage feature that tracks you as you move, though I generally find myself turning this off because I find it distracting. The webcam image itself looks a bit smoothed-out and overly processed, but white balance, auto-exposure, and auto-focus are all decent. It’s more than adequate for Zoom or FaceTime.</p>
<p>In PCs around this price, “making noise” is usually the only requirement for the speakers, and the quality of that noise is mostly an afterthought. The Neo’s speakers don’t reach nearly the “that sounds pretty good, actually” threshold of the MacBook Pro or even the 15-inch MacBook Air, but they do a decent job overall, playing vocals and other treble-y tones with good clarity and volume. But the overall effect is still a bit tinny, and there’s not much bass to speak of.</p>
                  </div>
              
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<div class="page-anchor-wrapper">
<h3>Ports in a storm</h3>
<div class="ars-lightbox align-fullwidth my-5">
          <div class="ars-gallery-1-up my-5">
  <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="900" data-pswp-height="450" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01.jpeg 900w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01-640x320.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01-768x384.jpeg 768w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01.jpeg" target="_blank" class="cursor-zoom-in">
    <img width="900" height="450" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01.jpeg" class="ars-gallery-image" alt="" aria-labelledby="caption-2143853" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01.jpeg 900w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01-640x320.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-01-768x384.jpeg 768w" sizes="auto, (max-width: 900px) 100vw, 900px" /></a>
      
  </div>
  <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content">
                    
                      Andrew Cunningham
                  
          </div>
  </div>
</div>
      <div class="flex flex-col flex-nowrap gap-5 py-5 md:flex-row">
  <div class="">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="900" data-pswp-height="450" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03.jpeg 900w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03-640x320.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03-768x384.jpeg 768w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03.jpeg" target="_blank" class="cursor-zoom-in">
    <img width="900" height="450" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03.jpeg" class="ars-gallery-image" alt="" aria-labelledby="caption-2143978" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03.jpeg 900w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03-640x320.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-03-768x384.jpeg 768w" sizes="auto, (max-width: 900px) 100vw, 900px" /></a>
      
  </div>
    <div class="md:hidden">
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content">
                    
                      Andrew Cunningham
                  
          </div>
  </div>
    </div>
  </div>
  <div class="flex-1">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="900" data-pswp-height="450" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02.jpeg 900w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02-640x320.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02-768x384.jpeg 768w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02.jpeg" target="_blank" class="cursor-zoom-in">
    <img width="900" height="450" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02.jpeg" class="ars-gallery-image" alt="" aria-labelledby="caption-2143977" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02.jpeg 900w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02-640x320.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/Neo-USB2-02-768x384.jpeg 768w" sizes="auto, (max-width: 900px) 100vw, 900px" /></a>
      
  </div>
    <div class="md:hidden">
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content">
                    
                      Andrew Cunningham
                  
          </div>
  </div>
    </div>
  </div>
</div>
<div class="hidden md:block">
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content left">
                    
                      Andrew Cunningham
                  
          </div>
  </div>
      <div class="ars-gallery-caption">
    <div class="ars-gallery-caption-content right">
                    
                      Andrew Cunningham
                  
          </div>
  </div>
  </div>
      </div>
<p>The MacBook Neo’s port situation may be its most confusing change from older MacBooks.</p>
<p>MacBooks sold in the last decade have generally had between two and four Thunderbolt ports, all of which have been (<a href="https://www.macrumors.com/2016/10/28/macbook-pro-tb3-reduced-pci-express-bandwidth/">mostly</a>) functionally equivalent. You can plug whatever you want into any of them, whether that’s a charger or a monitor or external storage or some kind of dongle, and they’ll all work the same way.</p>
<p>The MacBook Neo has two ports, and they look the same as any ports on any other MacBook. But they’re just regular USB-C ports rather than Thunderbolt ports, and they both do slightly different things. The leftmost port, if you’re looking at the laptop from the side, supports 10 Gbps USB 3 connections and can also drive a single external 4K 60 Hz display. The rightmost post is limited to 480 Mbps USB 2.0 speeds and doesn’t support external display output.</p>
<p>Both ports can charge the laptop. But for high-speed external storage, external displays, gigabit Ethernet dongles, USB-C docks and hubs, and any other accessories you might want to use with the Neo, the leftmost port is the most capable one.</p>
<p>To make up for the fact that these ports are totally unmarked and that no other MacBook asks you to keep this stuff straight, Apple has built some notifications into macOS to steer users in the right direction. Based on our testing, whenever you plug a USB 3-or-higher accessory into the USB 2 port, you’ll see a notification about how higher speeds are possible with the other port. These accessories still <em>work</em> in the USB 2 port, just with reduced performance.</p>
<figure class="ars-wp-img-shortcode id-2144548 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1440x810.jpeg 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678.jpeg" target="_blank">
              <img width="2560" height="1440" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678.jpeg" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3678-1440x810.jpeg 1440w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a>
            
          </div>
        </div>
          </div>
          <figcaption>
    
    
      The left port on the side of the Neo is a USB 3 port that supports display output and 10 Gbps data transfer speeds. The right port is a USB 2 port. Either can charge the laptop. There’s also a headphone jack.
              
          Credit:
          Andrew Cunningham
                  
          </figcaption></figure></div>
  </div>
      <p>Plugging a monitor or a display dongle into the USB 2.0 port will generate a slightly different notification telling you to use the other port for display output. If you’re trying to plug in a USB-C monitor with a USB hub and USB-PD charging, those features will still work through the USB 2.0 port, but display output won’t.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>All of this port stuff is downstream of Apple’s decision to use an A18 Pro processor in this Mac instead of an M-series processor—a chip designed for the iPhone 16 Pro, not a laptop with a bunch of I/O. Its USB controller supports a single 10Gbps USB-C port, because the iPhone only has one port; supporting a second 10Gbps USB-C port would have been a waste of silicon.</p>
<p>We might see this change over time. If Apple plans to <em>keep</em> putting iPhone chips in future MacBook Neos, <em>those</em> could be designed with more than one USB 3 port, in the interest of streamlining what is currently a non-deal-breaking but slightly annoying limitation of the MacBook Neo. It is a reminder that the decision to use a smartphone processor can affect functionality in ways beyond CPU and GPU core count. Bear this in mind as we talk about performance.</p>
<h3>Notes on external display support</h3>
<p>Apple says that the MacBook Neo supports a single external display, with a resolution and refresh rate of up to 4K at 60 Hz. This is also something that stems from the re-use of a smartphone chip—no one is attaching their iPhone to multiple external screens. But even the M1 Air supports a 6K display at up to 60 Hz, so it’s another place where the Neo is a small downgrade compared to every other Apple Silicon Mac.</p>
<p>I can confirm that a 1440p display works at 75 Hz, but I don’t have a comprehensive list of the refresh rates supported at lower resolutions. The Neo isn’t capable of driving the Studio Display or Studio Display XDR at their native 5K resolutions.</p>
<p>When connected to a 4K external display, all other MacBooks will offer a “more space” display mode with the same amount of usable desktop space as a non-Retina 2560×1440 screen. The MacBook Neo doesn’t offer this display mode. The default view gives you the usable space of a 1080p monitor with Retina-resolution graphics, or a native 4K resolution with apps that are mostly too tiny to see and use comfortably. Putting the display in any other mode means putting up with non-native resolutions and the resulting blurriness.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>You may or may not notice this if you use a 4K screen with your MacBook Neo. I used 27-inch 5K iMacs for years, so the “more space” 1440p view is what my eyes perceive as “normal;” this is also the same amount of usable desktop space you get at the default resolution when you use a Studio Display. This just isn’t possible with the Neo.</p>
<h3>Notes on charging and battery life</h3>
<p>Apple ships the Neo with a 20 W wall-wart charger identical to the one that comes with iPads, along with a 5-foot USB-C cable (unlike the Airs, this is just a white cable, not color-matched to the system). All other USB-C chargers I tested worked fine with the Neo. According to the System Information app, it’s incapable of recognizing charger wattages higher than 45 W.</p>
<p>Higher-wattage chargers <em>will</em> refill the Neo’s battery slightly faster than the 20 W charger—with a 45 W charger the laptop had charged from 0 to 66 percent in an hour. It went from 0 to just 43 percent in an hour with its 20 W charger.</p>
<p>Apple’s numbers indicate that the MacBook Neo is a step down in battery life from the MacBook Airs; Apple says the Neo can last for about 11 hours of wireless web browsing, down from 15 hours for the M1 Air and the 13-inch M5 Air. The Neo’s smaller 36.5 WHr battery may be partially responsible for this.</p>
<p>Our normal PCMark battery life test doesn’t work on Macs, but anecdotally after a few days of use I can say that I do notice the battery draining a bit faster than it does in a MacBook Air. I don’t think anyone will have any trouble getting a full workday out of the Neo with plenty of battery to spare, but the battery does feel easier to drain than other Apple Silicon Macs I’ve used.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<div class="page-anchor-wrapper">
<h2>Quantitative performance: A Mac with an iPhone inside</h2>
<p>The main MacBook Neo tech spec you’ll read the most about is its 8GB of RAM, and there’s plenty to say about it, and we’ll get to it in a minute. But there’s a reason we test things in real life, and it’s because the spec sheet doesn’t <em>always</em> give you the full picture.</p>
<p>Apple’s A- and M-series chips have always shared a lot of technology, but the MacBook Neo is the first time Apple has shipped a Mac that is literally using an iPhone processor in it. The Apple A18 Pro, originally shipped in the iPhone 16 Pro in late 2024, includes two high-performance CPU cores, four high-efficiency CPU cores, and five GPU cores (the chip can have a maximum of six, but one is disabled in the Neo’s iteration).</p>
<p>Though we’re also comparing it to the M5 MacBook Air and a few other laptops, we’ve focused on comparing the MacBook Neo to the old M1 MacBook Air, the closest thing the Neo has to a true predecessor. Our M1 Air is the high-end configuration with four high-performance CPU cores, four high-efficiency CPU cores, eight GPU cores, and 16GB of unified memory. Based on iPhone 16 Pro benchmarks, conventional wisdom held that the A18 Pro would mostly outperform or match the old M1, thanks to its newer CPU and GPU architectures.</p>
<div class="ars-lightbox align-fullwidth my-5">
          <div class="ars-gallery-1-up my-5">
  <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001.png" target="_blank" class="cursor-zoom-in">
    <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144556" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.001-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
  </div>
  </div>
      <div class="flex flex-col flex-nowrap gap-5 py-5 md:flex-row">
  <div class="">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002.png" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="768" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1024x768.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144557" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.002.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
  </div>
    
  </div>
  <div class="flex-1">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003.png" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="768" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1024x768.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144558" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.003.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
  </div>
    
  </div>
</div>

      </div>
<p>And in the Geekbench 6 benchmark, that’s true. Newer, faster performance cores allow the Neo to trounce the old M1 in Geekbench’s single-core performance tests, running around 42 percent faster than the M1. In the multi-core test, the M1 and the A18 Pro are roughly tied, with the M1 edging out the A18 Pro by just a couple percentage points. The Geekbench Compute test, which runs a few non-gaming GPU-accelerated workloads, also shows the M1 beating the A18 Pro by around 10 percent. Not nothing, but close to a wash, right?</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p><a href="https://arstechnica.com/gadgets/2023/02/geekbenchs-creator-on-version-6-and-why-benchmarks-matter-in-the-real-world/">I like Geekbench</a>. I think it does a good job of measuring what normal everyday computer performance feels like—mostly people need small bursts of fast performance, like when they open a file or launch an app or load a new browser tab, and then a bunch of low-power CPU cores that can juggle background tasks without killing the battery. Geekbench is good at measuring that. On balance, it’s fine that this is The One Benchmark Everyone Runs On Everything.</p>
<p>But what Geekbench <em>isn’t</em> is a test of sustained CPU or GPU performance over time. It’s not a good metric for how games will run, or how quickly your system will run some kind of app or media export that hammers one or more CPU cores for many minutes at a time.</p>
<p>And it’s these kinds of tests where the A18 Pro becomes less consistent. In heavy multi-core tests, the A18 Pro is actually quite a bit <em>slower</em> than the M1, and it’s the same when playing games. In a lot of measures, this is the slowest processor Apple has shipped in a Mac in six years, including the M1.</p>
<div class="ars-lightbox align-fullwidth my-5">
          <div class="ars-gallery-1-up my-5">
  <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004.png" target="_blank" class="cursor-zoom-in">
    <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144559" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.004-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
  </div>
  </div>
      <div class="flex flex-col flex-nowrap gap-5 py-5 md:flex-row">
  <div class="">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005.png" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="768" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1024x768.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144560" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.005.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
  </div>
    
  </div>
  <div class="flex-1">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006.png" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="768" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1024x768.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144561" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.006.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
  </div>
    
  </div>
</div>

          <div class="ars-gallery-thumbnails grid grid-cols-4 gap-3 sm:grid-cols-6">
                  <div class="aspect-square">
            <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007.png" target="_blank" class="cursor-zoom-in">
    <img width="640" height="480" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-640x480.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144562" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.007.png 2048w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a>
  </div>
          </div>
                  <div class="aspect-square">
            <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png" target="_blank" class="cursor-zoom-in">
    <img width="640" height="480" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-640x480.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144563" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png 2048w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a>
  </div>
          </div>
                  <div class="aspect-square">
            <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009.png" target="_blank" class="cursor-zoom-in">
    <img width="640" height="480" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-640x480.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144564" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.009.png 2048w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a>
  </div>
          </div>
              </div>
      </div>
<p>The various Cinebench tests have both single- and multi-core runs, each of which lasts for multiple minutes. Over many years of processor testing, I’ve found that most CPUs can deliver peak single-core CPU performance more or less indefinitely. It’s activating a bunch of cores at once that really amps up the power usage and the heat, which is normally why processors (especially in fanless laptops like the Neo and MacBook Air) have to ramp performance down a bit over time.</p>
<p>The A18 Pro isn’t like that. In a 10-minute single-core Cinebench 2024 run, a single A18 Pro P-core maintains its peak clock speed (around 4 GHz) for just a couple of seconds. It spends a few minutes hovering in the mid-3 GHz range, before falling below 3 GHz for most of the rest of the test.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>The M1 Air’s peak clock speed is a much lower 3.2 GHz. But it runs at that same, steady 3.2 GHz through the entire benchmark run. Overall, the MacBook Neo runs the Cinebench 2024 single-core test around 20 percent faster than the M1, substantially smaller than the 40-ish percent boost we saw in Geekbench.</p>
<p>That aggressive throttling behavior in single-core CPU benchmark bodes poorly for tasks where the A18 Pro is being asked to sustain performance over time—both for multi-core-heavy CPU-based workloads, and things like games that put demands on the CPU and GPU at the same time.</p>
<p></p><figure class="ars-wp-img-shortcode id-2144552 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-1440x1080.png 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001.png" target="_blank">
              <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001.png" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.001-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
            
          </div>
        </div>
          </div>
      </figure>
<p>In everything from the Cinebench multi-core test, to our Handbrake CPU-based video encoding test, to our 3D gaming benchmarks, the A18 Pro is consistently quite a bit slower than the M1. Generally, we found that the Neo is about 70 percent as fast as the M1 MacBook Air in the tests we could run. The Cinebench GPU tests won’t run on the Neo because it doesn’t have enough RAM.</p>
<p>To dig into what’s going on here, we turned to the Mac’s built-in <code>powermetrics</code> command-line tool. Like Activity Monitor, it can measure a whole lot of information about what your Mac’s CPU and GPU are doing, including clock speed for individual CPU cores and clusters of CPU cores, and power use for the CPU, the GPU, and the entire SoC as a whole.</p>
<p>I used its logging function (plus a bit of custom PHP from <a href="https://arstechnica.com/author/jason-marlin/">Ars Technical Director Jason Marlin</a> for taking that unwieldy log output and making it into a more manageable CSV file) to take a look at what the A18 Pro was doing over a few test runs and compared it to how the M1 MacBook Air behaved in the same tests. What we observed was that the A18 Pro still throttles its speed like it’s in a space-constrained smartphone, despite the Neo being a laptop that could theoretically make room for a larger passive heatsink.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p></p><figure class="ars-wp-img-shortcode id-2144553 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-1440x1080.png 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002.png" target="_blank">
              <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002.png" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.002-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
            
          </div>
        </div>
          </div>
      </figure>
<p>The A18 Pro’s P-cores can run at maximum clock speeds of up to around 4 GHz, substantially faster than the M1’s maximum of 3.2 GHz. But it can’t sustain that kind of clock speed for long. In extended single-core benchmarks, performance drops to the 3.7-to-3.5 GHz range within a minute or so, and they drop to the 2.9-to-3.2 GHz range after about five minutes. Both the M1 Air <em>and</em> the new M5 Air (4.46 GHz) are able to sustain their peak clock speeds indefinitely in single-core mode.</p>
<p>The chip’s clock speeds fall even faster during sustained multi-core performance tests, where the A18’s two P-cores fall well below the M5 and M1’s clock speeds within seconds—that the M1 has twice as many P-cores running at higher clock speeds helps explain why it beats the Neo in these kinds of tests.</p>
<p></p><figure class="ars-wp-img-shortcode id-2144554 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1440x1080.png 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png" target="_blank">
              <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
            
          </div>
        </div>
          </div>
      </figure>
<p>Even the A18 Pro’s E-cores act differently than they do in other passively cooled Apple laptops. The E-cores in both the M1 and M5 Airs are both capable of maintaining a pretty consistent clock speed from the start of the Handbrake encoding test to the end—both have more peaks and valleys than the single-core test, but neither exhibits any kind of sustained downshift in clock speed. The A18 Pro’s E-cores do maintain a clock speed of around 2.4 GHz for a couple of minutes when they’re all engaged simultaneously, before dropping into the 2.0-to-2.1 GHz range for the remainder of the test.</p>
<p>I don’t <em>think</em> this is thermal throttling, where the CPU is running too hot and needs to rein in speeds to cool itself down—Apple’s software tools don’t measure the temperature of any system components, but the only time the Neo gets even remotely warm is when you’re charging it. It seems more like the chip just wants to operate inside of a ~4 Watt power envelope when all of its CPU cores are engaged—for all the spikiness of the P- and E-core clock speeds in our various tests, you’ll note that the A18 Pro’s power consumption is <em>very</em> consistent after a minute or two.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p></p><figure class="ars-wp-img-shortcode id-2144554 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1440x1080.png 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png" target="_blank">
              <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo-throttling.003-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
            
          </div>
        </div>
          </div>
      </figure>
<p>That the MacBook Neo is using a smartphone chip was not a surprise. What surprised me a little was that it’s still acting like it’s in a smartphone, with short bursts of peak performance in both single- and multi-core tests that fall off sharply to keep the chip inside a tiny power envelope.</p>
<p>This makes the A18 Pro incredibly efficient. While it takes longer than any other chip to encode the video, that 4 W average power consumption (compared to 11.5 W for the M1 Air and 16.1 W for the M5 Air) means that it uses a little less power in total than the likes of the M1 and M5 to do the same amount of work.</p>
<div class="ars-lightbox align-fullwidth my-5">
          <div class="ars-gallery-1-up my-5">
  <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png" target="_blank" class="cursor-zoom-in">
    <img width="2048" height="1536" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144563" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.008-1440x1080.png 1440w" sizes="auto, (max-width: 2048px) 100vw, 2048px" /></a>
  </div>
  </div>
      <div class="flex flex-col flex-nowrap gap-5 py-5 md:flex-row">
  <div class="">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010.png" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="768" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1024x768.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144565" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.010.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
  </div>
    
  </div>
  <div class="flex-1">
    <div class="ars-lightbox-item relative block h-full w-full overflow-hidden rounded-sm">
  <a data-pswp-width="2048" data-pswp-height="1536" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011.png 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1440x1080.png 1440w" data-cropped="true" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011.png" target="_blank" class="cursor-zoom-in">
    <img width="1024" height="768" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1024x768.png" class="ars-gallery-image" alt="" aria-labelledby="caption-2144566" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1024x768.png 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-640x480.png 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-768x576.png 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1536x1152.png 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-980x735.png 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011-1440x1080.png 1440w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/MacBook-Neo.011.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a>
  </div>
    
  </div>
</div>

      </div>
<p>It seems as though Apple has left some performance on the table here—based on our testing, even a 7 W or 8 W power envelope would have been enough to improve its sustained clock speeds, while still keeping overall power consumption reasonably low. It’s possible that Apple keeps the power envelope low to help extend the battery life, since the Neo’s 36.5 WHr battery is only 73 percent as big as the M1 Air’s 49.9 WHr battery, and it comes with a similar screen, but it’s hard to say for sure.</p>
<p>When contacted for comment, Apple declined to answer our questions about the Neo’s performance, power consumption, or cooling solution.</p>
<div class="page-anchor-wrapper">
<h2>Qualitative performance: A18 Pro mostly holds up</h2>
<p>I have dug into throttling behavior, run a bunch of benchmarks, and made a bunch of charts because I think the data helps demonstrate who the MacBook Neo isn’t for. But even though they show many heavier workloads where the A18 is substantially weaker than the old M1, they also help illustrate why day-to-day performance feels fine.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>As Howard Oakley at the Eclectic Light Company outlines <a href="https://eclecticlight.co/2026/02/08/last-week-on-my-mac-why-e-cores-make-apple-silicon-fast/">here</a>, macOS attempts to keep low-priority and background tasks running on the E-cores whenever possible, and our data suggests that the A18 Pro’s E-cores are less throttling-prone than its P-cores are. And while its P-cores can only maintain their peak clock speeds for a minute or so in single-core tasks, “a minute or so” is more than sufficient for opening a browser tab or launching an app.</p>
<p>I mostly tried to use the MacBook Neo the way I’d use my current daily driver, a 15-inch M3 MacBook Air with 512GB of storage and 24GB of RAM:</p>
<ul><li>I opened a bunch of Microsoft Edge tabs for writing and researching articles;</li>
<li>I played YouTube videos while also hopping between other browser tabs and apps;</li>
<li>I used the Photos app to import, adjust, and export high-resolution RAW images;</li>
<li>I ran PHP scripts to convert log files into large CSV files and then worked with those CSV files in Numbers and Excel, pasting the data into Keynote to make charts;</li>
<li>I opened multiple hour-long audio projects in Audacity for editing and exporting;</li>
<li>I edited a high-resolution graphic in <a href="https://arstechnica.com/gadgets/2025/10/canvas-new-affinity-app-is-free-to-use-but-locks-ai-features-behind-a-subscription/">the new unified Affinity app</a>;</li>
<li>I used the Bambu Studio app to open 3D print files and preview, slice, and print them, and monitor the progress of the prints;</li>
<li>While using an external 4K display, I recorded a podcast in Audacity while simultaneously video chatting over Zoom and jumping between different browser tabs and Notes app research notes;</li>
<li>I left Slack and Discord and Spotify and the Dropbox agent and the WireGuard VPN software active in the background basically constantly, while playing music to a HomePod via Airplay.</li>
</ul><p>And the MacBook Neo mostly held up! Editing the RAW photos, exporting MP3s, and slicing 3D print files all took a few beats longer than I was used to. The Zoom-with-external-monitor-connected scenario made for a video call that hiccuped a few times. I definitely noticed I was using a cheaper, slower computer.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>But the things I wanted to do, I could mostly do. I wasn’t editing huge Final Cut projects (I opened Final Cut Pro to see if it would open; it did) or complex multi-track Logic soundscapes, or compiling apps in Xcode. I didn’t try much gaming. I did not attempt to create a virtual machine. If I were editing more than a handful of RAW photos at a time, I would probably have found the laptop’s performance frustrating. If you think there’s even a remote chance you might want to do those things, don’t even try to get the Neo. It won’t be enough computer for you.</p>
<p>Because where the processor doesn’t hold you back, the 8GB RAM limit certainly will.</p>
<h3>The 8GB memory problem: Under pressure</h3>
<p>As far as I’m concerned, the best change Apple has made to its entire Mac lineup in the years since launching the Apple M1 came in October of 2024, when it <a href="https://arstechnica.com/apple/2024/10/theres-no-m4-macbook-air-this-week-but-the-8gb-m2-and-m3-models-are-going-away/">increased the baseline amount of memory</a> in almost every Mac it sold from 8GB to 16GB without raising prices. It was effectively a price cut, making a nearly universally recommended upgrade “free” and knocking $200 off the price of the higher-end memory configurations.</p>
<p>The MacBook Neo’s single largest functional compromise is that it’s stuck with a non-upgradeable 8GB of RAM, another compromise imposed by its use of the A18 Pro (Apple only makes it with 8GB of RAM, and either using the cutting-edge A19 Pro with 12GB of RAM or spending the money making a special A18 Pro with more RAM <em>just</em> for the MacBook Neo would defeat the purpose).</p>
<p>There’s nothing magical about 16GB of memory. Many people can get by with less; a few people genuinely need a lot more. But right now, I’d it’s the amount of memory most people need if they never ever want to think about their computer’s memory.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>In the years I’ve been selling, servicing, and writing about computers, I’ve lived through eras where that amount of memory has been 512MB, and 1GB, and 2GB, and 4GB, and 8GB. Right now, 4GB is the “will boot you to a desktop and run an app” amount, and 16GB is the “don’t need to think about it” amount.</p>
<p>Having a computer with 8GB of RAM in 2026 puts you in a weird zone where you can <em>mostly</em> use your computer to do <em>most</em> things, and you’ll only occasionally run into an app that will refuse to run at all (right now, usually but not exclusively games like <a href="https://arstechnica.com/gaming/2025/07/cyberpunk-2077s-mac-port-will-run-on-all-apple-silicon-chips-even-the-aging-m1/"><em>Cyberpunk 2077</em></a>). But sometimes you’ll open one browser tab or app window too many, and you’ll need to think about quitting or closing some things you aren’t actively using.</p>
<figure class="ars-wp-img-shortcode id-2144542 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="998" data-pswp-height="356" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure.jpeg 998w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure-640x228.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure-768x274.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure-980x350.jpeg 980w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure.jpeg" target="_blank">
              <img width="998" height="356" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure.jpeg" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure.jpeg 998w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure-640x228.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure-768x274.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/memory-pressure-980x350.jpeg 980w" sizes="auto, (max-width: 998px) 100vw, 998px" /></a>
            
          </div>
        </div>
          </div>
          <figcaption>
    
    
      With just 8GB of RAM, the MacBook Neo is regularly under memory pressure.
              
          Credit:
          Andrew Cunningham
                  
          </figcaption></figure></div>
  </div>
      <p>The macOS Activity Monitor’s Memory tab calls this “memory pressure.” When you’ve got enough memory to do whatever it is that you’re doing, the timeline is green, everything is fine. When you’re running up against the confines of your physical memory, the timeline turns yellow, and you’ve got memory pressure.</p>
<p>Memory pressure doesn’t mean your system starts collapsing, or that it becomes a totally unresponsive flipbook. It just means <em>pressure</em>. You are trying to use more memory than your system has, and it’s working in the background to move things to your disk so that the computer can keep working, and the system resources tied up in doing <em>that</em> are not available to the user.</p>
<p>Without Activity Monitor open, you can tell you’re experiencing memory pressure when an app takes a beat or two longer to load than you expected, or when a browser tab you had open recently had to reload when you switched back to it, or when your video call starts dropping frames.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>I’ve been able to use the MacBook Neo mostly as I would use my regular MacBook Air, but it’s also experiencing memory pressure pretty much constantly. It subtly degrades the experience in ways that didn’t make the Neo miserable to use, but which <em>did</em> make switching back to my 24GB M3 Air or even my 16GB M1 Air a bit of a relief.</p>
<p>Beyond the weaker processor and GPU, the thing that gives me pause about this particular version of the MacBook Neo is that the memory pressure problem is not going to get better over time. The Neo is usable enough right now; going forward, you’re trusting Apple and every app developer to keep 8GB users in mind while maintaining their software. Hopefully it will stay on the right side of “usable” for another two or three years at least, but you’re rolling the dice.</p>
<p>If there’s good news, it’s that virtually any future hardware refresh for the Neo would <em>have</em> to come with more memory than this. The A19 Pro in this year’s iPhone 17 Pro includes 12GB of RAM, which obviously is not as much as 16GB but would definitely be enough that most people wouldn’t need to worry about it. <a href="https://arstechnica.com/gadgets/2026/03/apple-keeps-the-ipad-air-fresh-with-m4-chip-upgrade-and-12gb-of-ram/">The new iPad Air’s cut-down M4</a> is another possible direction, with fewer CPU and GPU cores than the typical M4 but 12GB of RAM instead of 8 or 16GB.</p>
<div class="page-anchor-wrapper">
<h2>A good value, but with hard limits</h2>
<figure class="ars-wp-img-shortcode id-2144545 align-fullwidth"><div>
              <div class="ars-lightbox">
          <div class="ars-lightbox-item">
            <a class="cursor-zoom-in" data-pswp-width="2560" data-pswp-height="1440" data-pswp-srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1440x810.jpeg 1440w" data-cropped="false" href="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655.jpeg" target="_blank">
              <img width="2560" height="1440" src="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655.jpeg" class="fullwidth full" alt="" srcset="https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655.jpeg 2560w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-640x360.jpeg 640w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1024x576.jpeg 1024w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-768x432.jpeg 768w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1536x864.jpeg 1536w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-2048x1152.jpeg 2048w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-384x216.jpeg 384w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1152x648.jpeg 1152w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-980x551.jpeg 980w, https://cdn.arstechnica.net/wp-content/uploads/2026/03/IMG_3655-1440x810.jpeg 1440w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /></a>
            
          </div>
        </div>
          </div>
          <figcaption>
    
    
      The MacBook Neo.
              
          Credit:
          Andrew Cunningham
                  
          </figcaption></figure></div>
  </div>
      <p>Here is what the MacBook Neo is not: It is not a replacement for a MacBook Air. Even compared to the old M1 version, the Neo makes several compromises in ports, keyboard and trackpad features, screen quality, and performance that collectively mean that the number of people with an Apple Silicon MacBook who should “upgrade” to a new Neo is effectively zero.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="my-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>The MacBook Air is far from Apple’s fastest laptop, but the thing that has always felt good about the M1, M2, M3, M4, and M5 is that—especially when paired with 16GB or more of RAM—there’s very little that won’t run on one of those chips. The extra speed of a Pro or Max chip is absolutely useful for heavy multi-taskers, professional photographers and videographers, people running AI or machine-learning workloads, people who are still trying to make Mac gaming happen, and app developers running Xcode and spinning up the odd virtual machine for some testing. But you can generally use a baseline MacBook Air or Mac mini for that kind of work without wanting to throw your computer in a lake.</p>
<p>The MacBook Neo will sometimes fail to clear that bar, given its weaker smartphone chip (with its smartphone-style power envelope) and its 8GB RAM limit. There are already apps and games that won’t even run without at least 16GB of memory; others may run but do so poorly or inconsistently, especially for larger or more complex projects. I don’t think the MacBook Neo needs to be able to do all of this stuff, the same way <a href="https://arstechnica.com/apple/2025/03/apples-349-ipad-11-is-missing-a-lot-but-its-still-all-the-ipad-most-people-need/">the $349 A16 iPad</a> doesn’t need to be able to do everything an iPad Pro can. But as a more powerful, versatile, tinkerer-friendly operating system, macOS gives adventurous users more opportunities to bump up against the limits of the hardware than iOS or iPadOS do.</p>
<p>All of that said, I really like the MacBook Neo for its target audience. It could be a good first Mac for people who have only owned an iPhone and/or iPad; it could be a first laptop for any kid or cash-strapped college student, especially with the $100 educational discount; and it could be a reasonably good upgrade for all the beat-up, rickety, out-of-support 2010-to-2019-vintage non-Retina Intel MacBook Airs that I still see with some regularity in coffee shops and on trains.</p>
                  </div>
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>
        <div class="ad-wrapper with-label is-fullwidth">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
    <div class="mt-2.5 mx-auto px-[15px] sm:px-5 lg:grid lg:max-w-5xl lg:grid-cols-3 lg:gap-6 lg:px-8 xl:px-0">
      <div class="relative lg:col-span-2">
        <div class="post-content post-content-double">
<p>The hardware is cut down, right up to the edge of what we’d consider acceptable in some cases. But Apple has landed on the right side of the line most of the time, cutting features without messing up anything essential.</p>
<p>And in a turnabout for a company generally known for pricey products, Apple has also managed to hit a price that’s way under other “we tried to purpose-build a high-quality midrange laptop without making something terrible” laptops like the <a href="https://arstechnica.com/gadgets/2025/06/framework-laptop-12-review-im-excited-to-see-what-the-2nd-generation-looks-like/">Framework Laptop 12</a> ($799 for a config similar to the Neo, with a considerably worse screen) or Microsoft’s old <a href="https://arstechnica.com/gadgets/2022/07/review-microsofts-surface-laptop-go-2-has-a-lot-of-problems-but-i-like-it-anyway/">Surface Laptop Go</a> (now the “Surface Laptop, 13-inch,” and at $899, barely even trying to compete in the budget category). That Apple has done this in the middle of a horrible RAM and storage shortage that has other companies raising prices makes it feel like an even better deal.</p>
<h3>The good</h3>
<ul><li>A much cheaper Mac laptop than anything Apple has offered before, ever, and a nice mobile counterweight to the Mac mini (if you’re trying to compare the Neo mostly to refurbished and on-sale MacBook Airs, know that the Neo, too, will one day be available refurbished and on-sale—the base price <em>does</em> matter).</li>
<li>A18 Pro processor offers adequate performance for day-to-day computing.</li>
<li>Excellent Mac keyboard, pretty good trackpad, decent webcam and speakers, and a screen that’s better than most PCs in the same price range.</li>
<li>Cute, approachable design available in fun colors, though I am still waiting for the MacBook that’s available in the same rainbow of hues as the iMac.</li>
<li>No fan, and never runs hot.</li>
<li>Education pricing is still $100 less, which feels more significant for a $600 notebook than a $1,100 notebook.</li>
</ul><h3>The bad</h3>
<ul><li>Sometimes slower than an M1 MacBook Air from five-and-a-half years ago.</li>
<li>No backlit keyboard.</li>
<li>TouchID only in the $699/512GB model.</li>
<li>Port situation is confusing.</li>
<li>External display support is relatively limited.</li>
</ul><h3>The ugly</h3>
<ul><li>8GB RAM ceiling limits what you can do with the laptop, and it may age poorly.</li>
</ul></div>
          
  
  
              </div>
      <div class="dusk:bg-gray-100 hidden min-w-[300px] justify-self-end lg:block dark:bg-gray-50">
                  <div class="ad-wrapper is-sticky is-rail">
      <div class="ad-wrapper-inner">
        
      </div>
    </div>
                </div>
    </div>]]></description>
      <link>https://arstechnica.com/gadgets/2026/03/apple-macbook-neo-review-can-a-mac-get-by-with-an-iphones-processor-inside/</link>
      <guid>https://arstechnica.com/gadgets/2026/03/apple-macbook-neo-review-can-a-mac-get-by-with-an-iphones-processor-inside/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How China Learned to Love the Classics | The New Yorker]]></title>
      <description><![CDATA[<em class="SplitScreenContentHeaderWrapper-kYXvBM cbvbVk content-header article__content-header" data-testid="SplitScreenContentHeaderWrapper">The Chinese Communist Party has embraced the study of Greek and Latin—as, in some ways, an antidote to the modern West.<picture class="ResponsiveImagePicture-jKunQM gjCCFj SplitScreenContentHeaderLede-dhVTZD jloyWy responsive-image"><source media="(max-width: 767px)" srcset="https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_120,c_limit/JJ00007-26--square-web.jpg 120w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_240,c_limit/JJ00007-26--square-web.jpg 240w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_320,c_limit/JJ00007-26--square-web.jpg 320w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_640,c_limit/JJ00007-26--square-web.jpg 640w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_960,c_limit/JJ00007-26--square-web.jpg 960w" sizes="100vw" /><source media="(min-width: 768px)" srcset="https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_120,c_limit/JJ00007-26--square-web.jpg 120w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_240,c_limit/JJ00007-26--square-web.jpg 240w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_320,c_limit/JJ00007-26--square-web.jpg 320w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_640,c_limit/JJ00007-26--square-web.jpg 640w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_960,c_limit/JJ00007-26--square-web.jpg 960w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_1280,c_limit/JJ00007-26--square-web.jpg 1280w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_1600,c_limit/JJ00007-26--square-web.jpg 1600w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_1920,c_limit/JJ00007-26--square-web.jpg 1920w, https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_2240,c_limit/JJ00007-26--square-web.jpg 2240w" sizes="100vw" /><img alt="greek chinese pottery ceramics broken plate warrior dragon" class="ResponsiveImageContainer-dkeESL cQPiWi responsive-image__image" src="https://media.newyorker.com/photos/6977a6404e4d4b703c6e76cd/2:2/w_2560%2Cc_limit/JJ00007-26--square-web.jpg" /></picture></em><div class="body__inner-container"><figure data-testid="cne-audio-embed-figure" class="CneAudioEmbedFigure-cwqusU dGMPjV"><div data-testid="cne-audio-embed-container"></div></figure><p class="has-dropcap has-dropcap__lead-standard-heading paywall">In November, 2024, on the day of the U.S. Presidential election, Tim Whitmarsh landed in Beijing, jet-lagged and disoriented. It was the middle of the academic term at the University of Cambridge, where Whitmarsh holds the Regius Professorship in Greek. He had been flown business class halfway around the world and put up at a five-star hotel for what he had been told would be the first World Conference of Classics. What followed, he later <a data-offer-url="https://www.the-tls.com/politics-by-region/asian-politics/china-classics-essay-tim-whitmarsh" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.the-tls.com/politics-by-region/asian-politics/china-classics-essay-tim-whitmarsh&quot;}" href="https://www.the-tls.com/politics-by-region/asian-politics/china-classics-essay-tim-whitmarsh" rel="nofollow noopener" target="_blank">wrote</a>, was “the strangest and most momentous” event of his academic career.</p><p class="paywall">By eight o’clock the next morning, Whitmarsh was north of Beijing at the palatial Yanqi Lake international convention center. The venue, reportedly part of an almost six-billion-dollar construction project, had previously hosted the <em class="small">APEC</em> summit. Whitmarsh was ushered into a side room with distinguished guests, among them Lina Mendoni, the Greek minister of culture. The presiding politician was one of Xi Jinping’s closest confidants: China’s propaganda chief, Li Shulei. Li shook hands with Whitmarsh and exchanged platitudes with the other guests. It wasn’t until Whitmarsh had been herded into the main hall that he grasped what he’d signed up for: “a geopolitical event, not an intellectual one,” as he put it, with hosts including Greece and China’s ministries of culture.</p><div><div class="ConsumerMarketingUnitThemedWrapper-kjbXjp gnOkbl consumer-marketing-unit consumer-marketing-unit--article-mid-content" role="presentation" aria-hidden="true"></div><p class="paywall">Inside a conference hall roughly the size of a football field sat hundreds of people—ambassadors, politicians, and scholars. At the podium, Li read out a letter from Xi, which described ancient Greece and China as two civilizations that have shaped humanity’s development from opposite sides of Eurasia. Xi went on to encourage their cultural exchange and announced the establishment of a Chinese School of Classical Studies in Athens.</p><p class="paywall">Whitmarsh, who, with other Western-trained scholars, had led a group called the <a data-offer-url="https://www.amazon.com/Postclassicisms-Collective/dp/022667231X" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.amazon.com/Postclassicisms-Collective/dp/022667231X&quot;}" href="https://www.amazon.com/Postclassicisms-Collective/dp/022667231X" rel="nofollow noopener" target="_blank" data-aps-asin="022667231X" data-aps-asc-tag="">Postclassicisms Collective</a>, realized that he had prepared the wrong speech. In the years since Donald Trump entered politics, emboldening fascists and white supremacists who held rallies deploying Roman imagery, Whitmarsh and the others had come to repudiate a traditional view of their field that he summed up as the “passing of a baton, down through the ages from like-minded person to like-minded person.” When it came time for Whitmarsh to speak, he argued that ancient texts didn’t spring from some timeless ur-culture, and that they should not be treated as such. “ ‘Classical Greece,’ ” he said to the Chinese and Greek dignitaries, is “an invention of the classical Greeks themselves.”</p></div><div class="body__inner-container"><p class="paywall">When we met for drinks two months later, Whitmarsh wondered whether he might have accidentally offered a warning for China: “Maybe it was the right speech after all,” he told me.</p><p class="paywall">The World Conference of Classics had all the signs of a typical political spectacle, intended to cultivate appreciation for Chinese culture abroad. Yet Li and other scholars—many of whom can recall a time when their own intellectual traditions were denounced by Mao Zedong as “feudal dross”—also expressed admiration for the Western classics. One keynote at the conference was delivered by Liu Xiaofeng, one of the most prolific translators of ancient Greek thought into Chinese, and the gathering’s official theme was about “mutual learning.” The enthusiasm, in China, for Western classics also comes from below. In the years before Secretary of State Marco Rubio threatened to “aggressively” revoke Chinese student visas, nearly three hundred thousand Chinese enrolled at U.S. universities each year. Thousands learned ancient Greek and Latin. Many returning Chinese scholars brought their Western training and methodologies back to the Chinese academy, prompting university officials to find ways to categorize—and make use of—their skills.</p><p class="paywall">Even as foreign textbooks are banned and news broadcasts portray Western societies as gun-toting hellscapes, Chinese universities are hiring Greco-Roman classicists. One Beijing university recently completed a new translation of Plato. Another university established a research center, led by an Oxford professor, that puts ancient Chinese texts in conversation with other classical textual traditions, including Greek and Latin. The reason for the classics fervor varies depending on whom you ask, but most scholars agree that Chinese officials tend to see the Western classics as a complement to their politics. In recent years, Xi has made “cultural confidence” a cornerstone of national policy, referring to pride in Chinese traditions and values. Across China, archeological museums and exhibitions are multiplying, and neglected villages are being refurbished into stage-set “ancient” towns. At universities, the study of ancient Chinese texts has historically been scattered across disciplines; now, under government direction, universities are trying to gather that scholarship in new classics departments where, one theory goes, ancient truths can be nurtured and passed down. In 2024, Renmin University, in Beijing, became the first university in China to offer an undergraduate major in Chinese classical studies. Last March, Sichuan University opened a classics department, aiming to educate students to be “conversant in both Chinese and Western learning.” “When China looks at the world, they want to be like Greece,” Martin Kern, a Princeton Sinologist and keynote speaker at the World Conference of Classics, told me. “Greece is for Europe what China is for East Asia. You guys have Socrates. We have Confucius.”</p><p class="paywall">By now, it is almost a cliché to say that the Western classics are in crisis. During the past half dozen years, around ten universities and colleges have closed their classics departments or programs, with some folded into larger humanities units. Western classicists look to the classics revival in China with a mix of awe, envy, and hesitation: a geopolitical rival could very well value their discipline more than their home institutions. In 2023, Shadi Bartsch, a classicist at the University of Chicago, covered the cresting interest among Chinese intellectuals, in ancient Greek and Roman texts, in “<a data-offer-url="https://www.amazon.com/dp/0691229597" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.amazon.com/dp/0691229597&quot;}" href="https://www.amazon.com/dp/0691229597" rel="nofollow noopener" target="_blank" data-aps-asin="0691229597" data-aps-asc-tag="">Plato Goes to China</a>.” From late Qing reformers inspired by Athenian citizenship to nationalists who draw on Plato to bolster China’s political ideology, Bartsch shows how supple ancient texts are in the hands of interpreters. Yet she also acknowledged the upsides of a foreign government’s support for her field. “There is real interest in the question of whether China is going to become the main protector of the western classics,” she told me over e-mail.</p></div><div class="body__inner-container"><p class="has-dropcap has-dropcap__lead-standard-heading paywall">When I heard that China was hosting a lavish event with esteemed foreign classicists, I was curious: Who had orchestrated this? The story, according to several scholars I spoke to, begins in 2021, when Chinese and Greek education officials started setting up research centers—one in China and one in Greece—aimed at deepening understanding of the two ancient civilizations. In February, 2023, as Greek administrators prepared to celebrate the opening of a center in Athens, they received an unusual suggestion from the local Chinese Embassy: write a letter to Xi Jinping. One administrator told me that he was baffled, but that the embassy staff seemed confident that something would come of it.</p><p class="paywall">The inaugural ceremony for the so-called Center of Greek and Chinese Ancient Civilizations was attended by Sun Chunlan, a Chinese Vice-Premier at the time. Sun brought with her a reply letter from Xi Jinping congratulating the Greek scholars on the center’s opening. In the following weeks, Chinese media visited the center to report on how its then president had been <a data-offer-url="https://www.chinadailyhk.com/hk/article/318329?utm_source=chatgpt.com" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.chinadailyhk.com/hk/article/318329?utm_source=chatgpt.com&quot;}" href="https://www.chinadailyhk.com/hk/article/318329?utm_source=chatgpt.com" rel="nofollow noopener" target="_blank">honored</a> by Xi’s reply. “Glittering at each other, from each end of the Eurasian continent,” Xi had written, China and Greece should work together to promote mutual learning. The letter codified the idea that the modern West—defined by liberalism, constitutionalism, and multi-party democracy—could be separated, conceptually, from the ancient West, as represented by Greece and Rome. In China’s civilization-building cause, the former was an ideological adversary; the latter could become an ally.</p><p class="paywall">With Xi’s approval, momentum built quickly. One of the Chinese ministries involved in the joint centers helped organize the World Conference of Classics. They tapped China’s top academic institutions—Peking University, Renmin University, and Tsinghua University, among others—to draw up guest lists, and the universities relied in part on Western-educated faculty to send out the invitations. One of the invited professors, Jonathan Ready, of the University of Michigan, recalled feeling as taken aback as Whitmarsh. He had also flown business class, and had been squired to the front of the assembly for reasons he could not explain. “It was the most lavish conference I have ever, and will ever, go to,” he told me.</p><p class="paywall">Ready had been invited by a former student named He Yanxiao, whom he had taught at Indiana University, and who eventually went on to a postdoc at Tsinghua University. In December, 2024, I met up with Yanxiao for dinner in Beijing. A lanky bespectacled man in his early thirties, Yanxiao recalled that his interest in classics began during his freshman year of high school, when he encountered a Chinese translation of <a data-offer-url="https://www.amazon.com/dp/0140268863" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.amazon.com/dp/0140268863&quot;}" href="https://www.amazon.com/dp/0140268863" rel="nofollow noopener" target="_blank" data-aps-asin="0140268863" data-aps-asc-tag="">the Odyssey</a>. Like a true Marxist, he told me, he was searching for references to slavery, but he kept getting distracted by the tale. “I just found it so beautiful,” he said. He resolved to teach himself ancient Greek. Few resources existed for Chinese to study Greek at the time, but a new pair of introductory textbooks had been published recently by Liu Xiaofeng, the prolific translator.</p><p class="paywall">Liu was then a philosophy professor at Sun Yat-sen University in southern China, where he taught ancient Greek and Latin. He has since produced or edited several hundred translated works and interpretations. He is best known in the West, however, for his popular writings on the philosopher Leo Strauss, in the early two-thousands, which sparked what the Chinese media dubbed “Strauss fever.” In the years following Deng Xiaoping’s turn toward a capitalist economy, some Chinese intellectuals felt a kind of spiritual malaise; Deng’s reforms had failed to provide moral direction for a vast and proud former empire. Liu began to understand China’s aimlessness in the language of Strauss, who famously argued that Western civilization had strayed from its ideals of “Jerusalem and Athens.” (“How could I be so close to this person?” Liu once wrote.) Liu proposed that the aim of Chinese intellectuals should be to “rebuild the spirit of Chinese traditional civilization,” by studying the ancient texts of the West. It was no accident, Liu wrote, that Western superpowers once schooled their future leaders in ancient Greek and Latin. China, Liu concluded, needed a classics department.</p></div><div class="body__inner-container"><p class="paywall">Until recently, Liu was a noisy member of the Chinese intelligentsia, with little influence in politics. But, with Xi Jinping’s endorsement of the classics, Liu’s Straussian ideas have percolated into the upper echelons of the Party. In 2024, three of Liu’s protégés entered a newly established classics research office at the Chinese Academy of Social Sciences, a state think tank with close ties to policymakers, multiple Chinese classicists told me. They became integral players in the organization of the World Conference of Classics.</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">Yanxiao devoted himself to mastering the Confucian classics, and he eventually looked to study abroad, transferring, as a college junior, to Indiana University. There, Yanxiao began to realize how particular Liu’s approach to antiquity was. Classics historiography, which Yanxiao was learning at Indiana, makes you “function like a detective.” “You want to see how history is narrated, so you collect all kinds of evidence,” he told me. For Liu, by contrast, the study of the classics seemed almost subservient to a process of cultural empowerment. In a 2015 article, ten foreign-educated Chinese scholars were interviewed on how to institutionalize classics in China. Among the points they seemed to agree on was their wish to distance themselves from Liu’s approach. “Westerners do not speak of ‘usefulness,’ ” Zhang Wei, of Fudan University, said. In the fall of 2016, Yanxiao entered the Ph.D. program in ancient history at the University of Chicago. Soon after, classics became increasingly embroiled in America’s culture wars. White nationalists at Charlottesville marched hoisting Roman flags, and far-right internet personalities adopted Roman pseudonyms. A field beset by declining enrollments faced a reckoning over its role—complicity, even—in the ideologies of Western superiority that animated white supremacists. These tensions came to the fore in 2019, during an annual meeting, in San Diego, of the Society for Classical Studies. (It happened to be Yanxiao’s first time at the conference.) At a panel titled “The Future of Classics,” a Princeton historian of Rome named <a href="https://www.newyorker.com/books/book-currents/dan-el-padilla-peralta-on-learning-how-to-combat-loss">Dan-el Padilla Peralta</a> presented data showcasing the underrepresentation of Black and minority authors in top classics journals. During the Q. &amp; A., an independent scholar named Mary Frances Williams stood up to challenge the panelists. “Maybe we should start defending our discipline,” she said. The classics, after all, were the foundation of Western ideals like liberty, democracy, and freedom. Williams went on to say to Padilla Peralta, “You may have got your job because you’re Black, but I would prefer to think you got your job because of merit.” He replied that he wanted nothing to do with the vision of classics that Williams had outlined. “I hope the field dies,” he said. “And that it dies as swiftly as possible.”</p><p class="paywall">For many classicists, the “incident,” as they now call it, made clear that a selective vision of the field had undermined the authority of scholars from marginal communities. “Our field was, like, What are we doing?” Christopher Waldo, an Asian American classicist at the University of Washington, recalled. “There’s not just one thing that Greco-Roman antiquity signifies.” That year, Waldo created the Asian and Asian American Classical Caucus, which promotes the study of how Asian and Asian American cultures have interpreted antiquity. Other affinity groups, including Trans in Classics and CripAntiquity, started congregating around the same time. Padilla Peralta described the aims of like-minded scholars as “de-centering Greece and Rome as the primary or main locus of intellectual innovation.”</p><p class="paywall">For some Chinese scholars, who turned to the Greco-Roman classics for the perceived wisdom and cultural capital it conferred, the focus on marginalized voices in antiquity was grating. In 2021, an anonymous Chinese doctoral student in the United States published an article that circulated widely among Chinese classics students, bemoaning the “absurd reality of American academia.” The author blamed Padilla Peralta for stoking a culture of denunciations, using terms that evoked the Cultural Revolution. A commenter on the article made the link more succinctly: “Down with Confucius, burn the Pantheon—different formula, familiar flavor.”</p><p class="paywall">Yanxiao told me that, in his first few years at the University of Chicago, he had not thought of himself as Asian. “I used to think we were all academics huddled in the ivory tower working toward one intellectual pursuit,” he told me. Yanxiao broke from that view in 2019, when he spent a year as an exchange student at the University of California, Berkeley. Later, he began reading academic work on K-pop. Scholars such as the ethnomusicologist Michael Fuhr saw K-pop as a reversal of long-standing narratives, especially in pop music, that accentuated the flow of culture from West to East. It was an alluring idea for Yanxiao, who was raised in an environment shaped by the reception, and rejection, of Western ideas. K-pop scholarship, Yanxiao said, “shocked him” into embracing his Asian identity.</p></div><div class="body__inner-container"><p class="paywall">In the enlarged vision of the classics slowly taking shape in the American academy, Yanxiao has found an intellectual foothold. He studies interactions between the eastern half of the Roman Empire and East Asia, and sheds light on how popular art forms were often misunderstood by their ancient critics. In the fall of 2024, he flew to Princeton, where he delivered a lecture on Roman pantomime, a dance form that once dominated theatres across the Mediterranean. Comparing élite Roman accounts that dismissed pantomime as a vulgar import from the East with the way K-pop had been received by some Anglophone critics, Yanxiao reframed pantomime as a transformative hybrid of “East” and “West”—between the Empire’s eastern provinces and Rome—rather than a corrupt derivative. Padilla Peralta, who attended the lecture, called the paper “spectacular.” Yanxiao had proved, Padilla Peralta told me, that people of diverse backgrounds, and the “interventions” they brought to the field, led to a “richening of the historical fabric, not to its impoverishment.”</p><p class="has-dropcap has-dropcap__lead-standard-heading paywall">When the pandemic broke out, in 2020, Yanxiao returned to China to write his dissertation. He hardly recognized the country. Electronic payment methods had become almost universal. Futuristic cafés and boba parlors dotted major cities. The progress didn’t seem to extend to the academy, however. In the fall of 2023, Yanxiao joined Tsinghua University, where his research confused professors who were accustomed to more conventional disciplinary lines. “People at Tsinghua wondered whether my interest in K-pop was a sign that I was intellectually unserious,” Yanxiao told me.</p><p class="paywall">Yanxiao worked to bridge China’s more conservative academy with the post-classicist current in the West. After the Society for Classical Studies published a special issue on race and racism following <a href="https://www.newyorker.com/tag/george-floyd">George Floyd</a>’s murder, he conducted an interview with one of the issue’s editors for the <em>Shanghai Review</em> <em>of Books</em>. In 2020, the University of California, Berkeley, renamed its classics department “Ancient Greek and Roman Studies.” Yanxiao interviewed the Berkeley professor James Porter about the reasons behind the change. Porter, who, with Tim Whitmarsh, was a member of the Postclassicisms Collective, suggested to Yanxiao that, as Chinese scholars develop their own classics field, they need not repeat the West’s problems. They could start with “post-classicism” and “work backwards,” he said.</p><p class="paywall">In the Western academy, the study of antiquity has moved toward a more fractious, intercultural vision of the past. Yanxiao feels that Chinese classics must make similar accommodations, incorporating different perspectives on culture and class, to remain globally relevant. Straussianism, Yanxiao feared, would “isolate Chinese classics” from his fellow-practitioners in the United States and Europe.</p></div><div class="body__inner-container"><p class="paywall">In this mission, Yanxiao has found allies, like Jinyu Liu, a professor of Roman history at Emory University, in Atlanta. Around 2014, Liu began bringing American classicists on lecture tours through Chinese universities. She hosts exchanges between Chinese and American classicists, and has created an online, peer-reviewed <a data-offer-url="https://dco.dickinson.edu/index.php/about#" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://dco.dickinson.edu/index.php/about#&quot;}" href="https://dco.dickinson.edu/index.php/about#" rel="nofollow noopener" target="_blank">database</a> with Dickinson College, in Pennsylvania, that works on Chinese translations of Greek and Latin texts. “We’re revolutionizing the way Chinese learn Greek and Latin,” Liu said. In 2017, Martin Kern, the Princeton professor, co-founded the International Center for the Study of Ancient Text Cultures, at Renmin University, with an early-China scholar named Xu Jianwei. They invite scholars of various antiquities—Greece, Rome, Mesopotamia, Israel, India, Japan, Egypt, and the Arab world—to present findings in their respective fields. “You realize many of the problems you encounter also exist in other classical traditions,” Xu told me. During one session in August, 2024, Xu discussed a theory as to why educators in ancient China preferred oral recitation as a way to teach: winters in the north were so frigid that basic tools like ink and brushes would freeze. Xu recalled the excitement of some of his interlocutors, including the Western classicist Glenn Most. “He said ‘I never thought of that!’ ” Xu told me with a smile. Questions about the weather’s impact on philological practice, Most thought, could be asked of ancient Greece as well.</p><p class="paywall">Yanxiao had mixed feelings about the World Conference of Classics. A part of him felt immense pride when Xi Jinping’s letter was being read out. “This really niche thing I’ve been pursuing since high school got such mainstream attention,” Yanxiao told me. “So many foreign scholars realized that China was investing heavily in classics—something they couldn’t imagine in their own countries.” To be a classicist in Xi’s China was to operate with a halo usually reserved for scientists and engineers. For Yanxiao and other classics scholars, this will translate into more job openings, conferences, and opportunities to publish and lecture. But everything he had learned in America made him chafe at the conference’s emphasis on timeless wisdom. As Whitmarsh <a data-offer-url="https://www.the-tls.com/politics-by-region/asian-politics/china-classics-essay-tim-whitmarsh" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.the-tls.com/politics-by-region/asian-politics/china-classics-essay-tim-whitmarsh&quot;}" href="https://www.the-tls.com/politics-by-region/asian-politics/china-classics-essay-tim-whitmarsh" rel="nofollow noopener" target="_blank">put it</a> in the <em>Times Literary Supplement</em> last January, in an article recounting his experience at the conference, “We were enjoined to celebrate diversity and respect between nations—or at least two of them—but not within them.”</p><p class="paywall">Last year, I accompanied Yanxiao to the annual Society for Classical Studies conference, held at a Marriott in downtown Philadelphia. Paper titles included “Queer Spaces in Pompeii?,” “Ecofeminist Narratives in Ovid’s Metamorphoses,” and “Ocean Vuong, Allusion, and the Limits of Interpretation.” Defenders of the new classics—with its incorporation of race, gender, pop culture, and comparative frameworks—see it as a more faithful representation of antiquity itself. “When you study the classics,” Whitmarsh told me, coherence is an illusion. “It’s more like a disorganized mash that we try to piece together.”</p><p class="paywall">Yanxiao had prepared a talk on the Xiongnu Empire, a formidable power that occupied some lands north of Han Dynasty China. As he stepped up to the lectern, the monitors flashed an image of the first slide: it was a scene from the movie “<a href="https://www.newyorker.com/culture/cultural-comment/crazy-rich-asians-and-the-end-point-of-representation">Crazy Rich Asians</a>.” Yanxiao began to recount the story of Eleanor Young, played by the actress Michelle Yeoh, who arrives at a grand London hotel with her family in the nineteen-nineties. She is turned away by the hotel staff, who, unaware that she is the new owner, claim they are “fully booked” and suggest she try “Chinatown.” On the next slide, Yanxiao shared a list of rejections he’d received from classics journals, along with the reviewer’s comments. “If I have Chinese material or say something about my ethnicity, the reviewers suggest that the research should belong in Sinology journals,” he said. “That’s what I call Chinatown Classics.”</p></div><div class="body__inner-container"><p class="paywall">Returning to the core of his talk, Yanxiao likened the Xiongnu’s impact on the West to that of the Mongols, who, a millennium later, would alter the cultural topology of Eurasia. To grasp this piece of Roman history, Yanxiao argued, one had to study the Xiongnu—and to understand the Xiongnu, one had to read Chinese.</p><p class="paywall">On the last day of the conference, I had coffee with Yanxiao at the Marriott lobby. The conversation turned to the future, and I asked him which country he saw himself settling in. Applying for jobs in China was difficult, Yanxiao told me, because his research still bewilders some scholars, who thought he’d been “brainwashed by American gender-and-identity politics.” Still, he had come to appreciate the convenience and comfort of life in China—its high-speed rail, e-payments, and ultra-fast delivery systems.</p><p class="paywall">Outside the hotel, the snow had turned into sleet. Yanxiao had just returned from a stroll through the Philly streets, where the cityscape made him feel alienated, he told me. The typical American city was not as comforting to him as a typical Chinese one. At the Marriott, though, a sunny, more sociable side of Yanxiao seemed to come out. Friends waved him over, and younger Chinese scholars sought his attention. Among classicists, Yanxiao told me, he “felt totally at home.” ♦</p></div></div>]]></description>
      <link>https://www.newyorker.com/news/annals-of-education/how-china-learned-to-love-the-classics</link>
      <guid>https://www.newyorker.com/news/annals-of-education/how-china-learned-to-love-the-classics</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Create custom subagents - Claude Code Docs]]></title>
      <description><![CDATA[Create and use specialized AI subagents in Claude Code for task-specific workflows and improved context management.]]></description>
      <link>https://code.claude.com/docs/en/sub-agents</link>
      <guid>https://code.claude.com/docs/en/sub-agents</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Oh my Posh 3]]></title>
      <description><![CDATA[<div class="col col--4"><h3> Beautiful &amp; Intelligent</h3><p>Transform your terminal with stunning themes and intelligent segments that display Git status, cloud info, language versions, system metrics, and 180+ other contextual details. Your prompt adapts to what you're working on.</p></div><div class="col col--4"><h3>⚡ Lightning Fast</h3><p>Built with Go for blazing performance. Smart caching and async operations ensure your prompt renders instantly, even with complex configurations and multiple segments. No more waiting for your terminal.</p></div><div class="col col--4"><h3> Universal Compatibility</h3><p>One configuration works everywhere - PowerShell, Bash, Zsh, Fish, Nu Shell, and more. Windows, macOS, Linux, WSL, containers, SSH sessions. Write once, use everywhere with zero vendor lock-in.</p></div>]]></description>
      <link>https://ohmyposh.dev/</link>
      <guid>https://ohmyposh.dev/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Impeccable: The missing upgrade to Anthropic's frontend-design skill]]></title>
      <description><![CDATA[<section class="antidote-section" id="antidote"><p>01
</p><h2 class="section-title">The Antidote</h2><div class="antidote-content"><p class="section-lead" data-reveal="">Anthropic's original frontend-design skill laid the foundation. Impeccable builds on it with curated patterns and anti-patterns across typography, color, layout, motion, and more.</p><p class="contribute-inline">Missing something? <a href="https://github.com/pbakaus/impeccable/issues/new?labels=pattern&amp;title=Pattern%20suggestion%3A">Suggest a pattern →</a></p></div></section><section class="solution-section" id="solution"><p>02
</p><h2 class="section-title">The Framework</h2><div class="solution-content"><p class="section-lead" data-reveal="">One comprehensive skill with deep expertise, plus 17 commands that form the language of design.</p></div></section><section class="commands-section" id="commands-section"><section class="platforms-section" id="downloads"><div class="install-terminal glass-terminal" data-reveal=""><p>install</p><div class="terminal-body"><div class="install-terminal-row">All tools<div class="install-terminal-cmd">$<code>npx skills add pbakaus/impeccable</code></div>Auto-detects your AI harness and installs to the right location</div><div class="install-terminal-row">Claude Code<div class="install-terminal-cmd">$<code>/plugin marketplace add pbakaus/impeccable</code></div>Then open<code>/plugin</code>to install from Discover tab</div><div class="install-terminal-row">Manual<div class="install-terminal-cmd install-terminal-cmd--download"><label class="prefix-toggle"> Prefix with <code>/i-</code></label></div>Contains all provider directories — extract to project root</div></div></div><div class="install-providers" data-reveal="">Works with<div class="install-providers-row"><div class="install-provider-badge"><img src="https://img.logo.dev/cursor.com?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="Cursor" width="20" height="20" />Cursor</div><div class="install-provider-badge"><img src="https://img.logo.dev/claude.ai?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="Claude Code" width="20" height="20" />Claude Code</div><div class="install-provider-badge"><img src="https://img.logo.dev/gemini.google.com?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="Gemini CLI" width="20" height="20" />Gemini CLI</div><div class="install-provider-badge"><img src="https://img.logo.dev/openai.com?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="Codex CLI" width="20" height="20" />Codex CLI</div><div class="install-provider-badge"><img src="https://img.logo.dev/github.com?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="VS Code Copilot" width="20" height="20" />Copilot</div><div class="install-provider-badge"><img src="https://img.logo.dev/antigravity.google?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="Antigravity" width="20" height="20" />Antigravity</div><div class="install-provider-badge"><img src="https://img.logo.dev/kiro.dev?token=pk_dtRHfeTyRzG5zZInUc65Xw&amp;size=64&amp;format=png" alt="Kiro" width="20" height="20" />Kiro</div></div></div></section><section class="changelog-section" id="changelog"><p>05
</p><h2 class="section-title">What's New</h2><div class="changelog-list" data-reveal=""><div class="changelog-entry"><p>v1.2.0 March 5, 2026</p><ul class="changelog-items"><li>Added Kiro support (<code>.kiro/skills/</code>)</li>
<li>Restored prefix toggle — download <code>i-</code> prefixed bundles to avoid naming conflicts</li>
<li>Audit and critique skills only suggest real, installed commands</li>
</ul></div><div class="changelog-entry"><p>v1.1.0 March 4, 2026</p><ul class="changelog-items"><li>Unified skills architecture — commands are now skills with <code>user-invokable: true</code></li>
<li>Added VS Code Copilot and Google Antigravity support (<code>.agents/skills/</code>)</li>
<li>New install flow: <code>npx skills add</code> as primary, universal ZIP as fallback</li>
<li>Added universal ZIP containing all 5 provider directories</li>
<li>Renamed <code>/simplify</code> to <code>/distill</code> to avoid Claude Code conflict</li>
</ul></div><div class="changelog-entry"><p>v1.0.0 February 28, 2026</p><ul class="changelog-items"><li>Initial release with enhanced frontend-design skill</li>
<li>17 design commands: /polish, /audit, /distill, /bolder, and more</li>
<li>Support for Cursor, Claude Code, Gemini CLI, and Codex CLI</li>
<li>Interactive command cheatsheet</li>
</ul></div></div></section><section class="faq-section" id="faq"><p>06
</p><h2 class="section-title">Frequently Asked Questions</h2><div class="faq-list" data-reveal=""><details class="faq-item"><summary class="faq-question">Where do I put the downloaded files?</summary>                                                            </details></div>
<details class="faq-item"><summary class="faq-question">Commands or skills aren't appearing. What do I do?</summary>                                                                 
        

</details><details class="faq-item"><summary class="faq-question">I'm new to AI harnesses. Where do I start?</summary>                 
  
    
   
               
</details></section><section class="consulting-section" id="consulting"><div class="consulting-content" data-reveal=""><div class="consulting-text"><h2 class="consulting-title">Work with me</h2><p class="consulting-desc">I help teams navigate AI transformation: upleveling developers, building AI-native workflows, and shipping products. Deep expertise in developer experience, design systems, and full-stack architecture.</p></div><div class="consulting-actions"><a href="https://impeccable.style/cdn-cgi/l/email-protection#aadacbdfc6eadacbdfc6c8cbc1cbdfd984c9c5c7" class="btn btn-primary">Get in touch </a><a href="https://buy.stripe.com/aFa3cwfsEe3G25R6i48Ra03" class="btn btn-secondary" target="_blank" rel="noopener">Leave a tip </a></div></div></section></section>]]></description>
      <link>https://impeccable.style/#hero</link>
      <guid>https://impeccable.style/#hero</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[デバッグはもう人間の仕事ではなくなった]]></title>
      <description><![CDATA[<div class="znc BodyContentViewer_headingAnchorStyle__qn_OJ"><p data-line="0" class="code-line">こんにちは、ダイニーの ogino です。</p><p data-line="2" class="code-line">弊社では、ほとんどの技術的な不具合の調査・解決を AI に丸投げできるようになりました。<br />これは単なるコードレベルのバグに限りません。本番環境や特定のユーザーだけでしか発生しない問題、インフラの設定ミスなど含めすべてに言える話です。</p><p data-line="5" class="code-line">Claude Code を使い始めてからここに至るまで、大きく 2 つ転換点がありました。</p><ol data-line="7" class="code-line"><li data-line="7" class="code-line">AI が本番データベース、ログ、Sentry などに直接アクセスできるようにした</li>
<li data-line="8" class="code-line">複数のエージェントが仮説を並列検証し、もう一体が対立してレビューするチーム構成にした</li>
</ol><p data-line="10" class="code-line">それぞれについて詳しく説明していきます。</p><p data-line="14" class="code-line">あなたが何か問題の調査をするとき、どこを見るでしょうか？どんな情報が必要でしょうか？<br /><strong>AI はそれと同じレベルの情報を見られるようになっていますか？</strong><br />もし答えが No なら、まず真っ先にそのギャップを埋めるべきです。</p><p data-line="18" class="code-line">例えば「XXX のアプリでエラーメッセージ YYY が表示された」という問い合わせがあったとして、その調査を以下の流れで行ったと想像してみてください。</p><ol data-line="20" class="code-line"><li data-line="20" class="code-line">エラーメッセージ YYY はコードの中の n 行目で発生している</li>
<li data-line="21" class="code-line">そこに到達し得るコードパスは 2 つしかなくて、それぞれで異なるログが内部的に記録される</li>
<li data-line="22" class="code-line"><strong>ログ</strong>を確認して、片方のコードパスに絞り込む</li>
<li data-line="23" class="code-line">そのコードパスに到達するのは通常あり得ず、データに不整合があると考えられる</li>
<li data-line="24" class="code-line"><strong>データベース</strong>を見て、実際に不整合があることを確認する</li>
<li data-line="25" class="code-line"><strong>データベース</strong>を見て、同様の事象の影響範囲を確かめる</li>
<li data-line="26" class="code-line">根本原因を特定し、コードを修正する</li>
</ol><p data-line="28" class="code-line">この時 AI がログやデータベースを参照できれば、最初から最後まで試行錯誤のループが完結して、調査が瞬時に終わります。そうでなければ、合間に必要な過程をいちいち人間が代行しなければいけません。</p><h2 id="skills-%E3%81%A8-cli-%E3%81%A7%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%95%E3%81%9B%E3%82%8B" data-line="30" class="code-line">Skills と CLI でデータにアクセスさせる</h2><p data-line="32" class="code-line">弊社の場合、問い合わせに対応するための情報源の大半は以下のいずれかになります。</p><table data-line="34" class="code-line"><thead data-line="34" class="code-line"><tr data-line="34" class="code-line"><th>情報ソース</th>
<th>AI からのアクセス</th>
</tr></thead><tbody data-line="36" class="code-line"><tr data-line="36" class="code-line"><td>コード</td>
<td>当然アクセスできる</td>
</tr><tr data-line="37" class="code-line"><td>Sentry</td>
<td>安定した公式 MCP がある</td>
</tr><tr data-line="38" class="code-line"><td><strong>データベース</strong></td>
<td>???</td>
</tr><tr data-line="39" class="code-line"><td><strong>ログ</strong></td>
<td>???</td>
</tr></tbody></table><p data-line="42" class="code-line">そこで AI がデータベースとログにもアクセスできるようにするため、<a href="https://gist.github.com/swen128/e31993c09f4fab962311d6c7080d5d09#file-bigquery-md" target="_blank" rel="nofollow noopener noreferrer">bigquery</a> と <a href="https://gist.github.com/swen128/e31993c09f4fab962311d6c7080d5d09#file-cloud-logging-md" target="_blank" rel="nofollow noopener noreferrer">cloud-logging</a> という Skills を追加しました。内容の詳細はリンク先の gist にありますが、要するに</p><ul data-line="43" class="code-line"><li data-line="43" class="code-line"><code>bq</code> / <code>gcloud</code> の CLI を使え</li>
<li data-line="44" class="code-line">よく使うデータの場所、クエリの仕方</li>
<li data-line="45" class="code-line">AI がよく陥る失敗ケースの対処方法</li>
</ul><p data-line="47" class="code-line">前提として、弊社では本番アプリケーションの RDB データを BigQuery にほぼリアルタイムで複製しています。そのため、<strong>本番環境に影響を出さず AI が安全にクエリを投げられるリードレプリカ</strong>として機能します。この前提情報がコンテキストに含まれているか否かで、AI の使い勝手が大きく変わりました。</p><p data-line="49" class="code-line">また、社内のエンジニアは全員 <code>gcloud</code> (と同時に <code>bq</code>) の CLI をインストールしています。そのため、<strong>追加の手間や認証が一切不要</strong>な点も優れていました。</p><p data-line="51" class="code-line">結果として、bigquery と cloud-logging は社内でトップレベルによく利用される Skills になっています。</p><p data-line="53" class="code-line"><img src="https://res.cloudinary.com/zenn/image/fetch/s--uz3yJnH0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_1200/https://storage.googleapis.com/zenn-user-upload/deployed-images/a47d613eaad3429893c2e252.png%3Fsha%3D7a44b95412082dcba20aa6a6321698d24ba65b72" alt="dashboard.png" class="md-img" /><br /><em><a href="https://zenn.dev/dinii/articles/28c8fcd041837d" target="_blank">社内 Claude Code 利用状況ダッシュボード</a>より。スキルのトリガー回数、利用人数で常に上位にいる</em></p><aside class="msg message">!
<div class="msg-content"><p data-line="57" class="code-line">BigQuery に保存されているデータについては、個人情報にアクセスできないように、マスキング処理やテーブルごとの権限管理がされています。</p></div>
</aside><h2 id="ai-%E3%81%AE%E9%81%8E%E5%89%B0%E3%81%AA%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%A8%A9%E9%99%90%E3%81%AB%E3%82%88%E3%82%8B%E4%BA%8B%E6%95%85%E3%82%92%E9%98%B2%E3%81%90" data-line="60" class="code-line">AI の過剰なアクセス権限による事故を防ぐ</h2><p data-line="62" class="code-line">AI に <code>gcloud</code> コマンドを与えるということは、単にログやデータを読み取るだけでなく、本番環境のインフラを消し飛ばす権限も同時に与えることになります。</p><p data-line="64" class="code-line">実際に AI がそんなことをする確率は極めて低いですが、ゼロではありません。</p><p data-line="66" class="code-line"><code>--dangerously-skip-permissions</code> で自走させつつ、安全も確保するためにはどうすべきでしょうか？<strong>最も確実なのは、クラウド側の IAM で守る</strong>方法です。</p><h3 id="claude-code-%E3%81%AE-permission-%E6%A9%9F%E8%83%BD%E3%82%92%E4%BF%A1%E7%94%A8%E3%81%99%E3%82%8B%E3%81%AA" data-line="69" class="code-line">Claude Code の permission 機能を信用するな</h3><p data-line="71" class="code-line">Claude Code の設定には、コマンド実行をパターンマッチで自動的に許可/拒否する機能があります。</p><div class="code-block-container"><p>.claude/settings.json</p><pre class="code-line" data-line="73">"permissions": {
  "allow": ["Bash(* --help *)"],
  "deny": ["Bash(rm -rf *)", "Bash(gcloud * deploy *)"]
}
</pre></div><p data-line="80" class="code-line">この機能を <code>--dangerously-skip-permissions</code> と組み合わせて危険なコマンドの実行を防げる、と紹介されているのをよく見かけますが、これは<strong>抜け穴だらけの脆弱な方法</strong>です。</p><p data-line="82" class="code-line"><code>rm -rf /</code> を拒否すると、AI は <code>rmdir /</code> や <code>rm -r -f /</code> といった抜け道を探ってきます。<br /><code>* --help *</code> を許可すると、 <code>rm -rf / --help</code> などのコマンドもすり抜けます。<br />スクリプトをファイルに書いて実行されたら、どんな deny ルールを設定しても検知できません。</p><p data-line="86" class="code-line">コマンドのブラックリストだけでは、危険な操作を防ぐのは原理的に不可能です。PreToolUse hook を使ってコマンドを検査する方法も、同じ問題を抱えています。</p><h3 id="ai-%E5%B0%82%E7%94%A8%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%A7%E6%A8%A9%E9%99%90%E3%82%92%E5%88%B6%E5%BE%A1%E3%81%99%E3%82%8B" data-line="89" class="code-line">AI 専用のサービスアカウントで権限を制御する</h3><p data-line="91" class="code-line">人間と AI で別のアカウントを使うようにすれば、IAM の仕組みに乗って AI の権限を適切に絞ることができます。具体的には次のような方法です。</p><ul data-line="93" class="code-line"><li data-line="93" class="code-line">AI 専用のサービスアカウント <code>ai-agent@your-project.iam.gserviceaccount.com</code> を用意する</li>
<li data-line="94" class="code-line">AI 専用の IAM 権限を付与する（読み取り権限や、開発環境のデプロイ権限など）</li>
<li data-line="95" class="code-line">人間のアカウントに、AI 用サービスアカウントを impersonate する権限を与える</li>
<li data-line="96" class="code-line">Claude Code の起動時に、環境変数で <code>gcloud</code> の AI 用トークンを渡す</li>
</ul><div class="code-block-container"><p>launch-claude.sh</p><pre class="code-line" data-line="99">SA="ai-agent@your-project.iam.gserviceaccount.com"
TOKEN=$(gcloud auth print-access-token --impersonate-service-account="$SA")
CLOUDSDK_AUTH_ACCESS_TOKEN="$TOKEN" GOOGLE_OAUTH_ACCESS_TOKEN="$TOKEN" claude
</pre></div><p data-line="106" class="code-line">こうすると、Claude の中で実行する <code>gcloud</code> コマンドには AI 用の権限が適用されます。</p><p data-line="108" class="code-line">しかしこれだけではまだ解決になっていません。AI が環境変数をリセットするなど、いくらでも制限を回避する方法が残っているからです。</p><h3 id="%E4%BA%BA%E9%96%93%E7%94%A8%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E8%AA%8D%E8%A8%BC%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AB%E8%A7%A6%E3%82%8C%E3%81%95%E3%81%9B%E3%81%AA%E3%81%84" data-line="111" class="code-line">人間用アカウントの認証トークンに触れさせない</h3><p data-line="113" class="code-line"><code>gcloud</code> CLI の認証トークンは <code>~/.config/gcloud</code> に保存されます。この中のファイルを AI が読めないようにすれば、人間と同じアカウントで認証するのを根本的に防ぐことが可能です。</p><p data-line="115" class="code-line">そこで、macOS の <code>sandbox-exec</code> (もしくは Linux の <code>bubblewrap</code>) を使うと、<br />Claude Code のプロセス内に限り、特定ディレクトリへのアクセスだけを遮断できます。</p><div class="code-block-container"><p>launch-claude-with-sandbox.sh</p><pre class="code-line" data-line="118">SA="ai-agent@your-project.iam.gserviceaccount.com"
TOKEN=$(gcloud auth print-access-token --impersonate-service-account="$SA")
POLICY='(version 1)(allow default)(deny file-read* file-write* (subpath "'"${HOME}"'/.config/gcloud"))'
exec sandbox-exec -p "$POLICY" \
  env \
    CLOUDSDK_CONFIG="$(mktemp -d)" \
    CLOUDSDK_AUTH_ACCESS_TOKEN="$TOKEN" \
    GOOGLE_OAUTH_ACCESS_TOKEN="$TOKEN" \
    claude "$@"
</pre></div><p data-line="136" class="code-line">前節で説明した Skills によって、調査の材料となる情報源は整いました。しかし、AI は検証が不十分なまま「おそらく〇〇が原因です」と結論を出しがちです。本当に正しい答えが得られるまで、何度も尋問を繰り返す必要があり負担になっていました。</p><p data-line="138" class="code-line">そこで <code>/ultra-debug</code> という Skill を作成し、尋問の作業も AI に任せるようにしました。</p><h2 id="agent-teams-%E3%81%A7%E4%BB%AE%E8%AA%AC%E6%A4%9C%E8%A8%BC%E3%81%A8%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%97%E3%82%92%E5%9B%9E%E3%81%99" data-line="140" class="code-line">Agent Teams で仮説検証とレビューのループを回す</h2><p data-line="142" class="code-line"><code>/ultra-debug</code> は Claude Code の Agent Teams 機能を使い、5 体の <code>debugger</code> と 1 体の <code>critic</code> でチームを作成します。</p><ul data-line="144" class="code-line"><li data-line="144" class="code-line"><a href="https://github.com/swen128/claude-plugins/blob/27b2b13ce4ff68d088e9d2f4073ce8dd274330e1/ultra-debug/skills/ultra-debug/SKILL.md" target="_blank" rel="nofollow noopener noreferrer">.claude/skills/ultra-debug/SKILL.md</a></li>
<li data-line="145" class="code-line"><a href="https://github.com/swen128/claude-plugins/blob/27b2b13ce4ff68d088e9d2f4073ce8dd274330e1/ultra-debug/agents/debugger.md" target="_blank" rel="nofollow noopener noreferrer">.claude/agents/debugger.md</a></li>
<li data-line="146" class="code-line"><a href="https://github.com/swen128/claude-plugins/blob/27b2b13ce4ff68d088e9d2f4073ce8dd274330e1/ultra-debug/agents/critic.md" target="_blank" rel="nofollow noopener noreferrer">.claude/agents/critic.md</a></li>
</ul><aside class="msg message">!
<div class="msg-content"><p data-line="149" class="code-line">このプロンプトにはドメイン固有の前提が一切含まれていないので、そのまま汎用的に使えます。 <a href="https://github.com/swen128/claude-plugins/tree/27b2b13ce4ff68d088e9d2f4073ce8dd274330e1/ultra-debug" target="_blank" rel="nofollow noopener noreferrer">プラグイン</a>としても公開しました。</p></div>
</aside><p data-line="152" class="code-line">動作の流れは以下の通りです。</p><ol data-line="154" class="code-line"><li data-line="154" class="code-line">問題の原因について、5 個の仮説を立てる</li>
<li data-line="155" class="code-line">仮説ごとに <code>debugger</code> をチームメイトとして起動し、それぞれが独立に証拠を集める</li>
<li data-line="156" class="code-line"><code>critic</code> が報告内容を批判的に検証する
<ul data-line="157" class="code-line"><li data-line="157" class="code-line">「X の後に Y が起きたと示したが、X が Y を引き起こした証拠は？」</li>
<li data-line="158" class="code-line">「その仮説が正しいなら、〇〇も真のはずだが検証したか？」</li>
<li data-line="159" class="code-line">「このバグを導入した PR はどれか？ 」</li>
</ul></li>
<li data-line="160" class="code-line">指摘を受けて、必要なら追加調査を行う</li>
<li data-line="161" class="code-line">最終的な根本原因と因果関係をまとめる</li>
</ol><h2 id="%E5%AE%9F%E4%BE%8B%3A-mac-%E3%81%AE%E5%A4%96%E9%83%A8%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%81%8C%E6%98%A0%E3%82%89%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C%E3%81%AE%E8%A7%A3%E6%B1%BA" data-line="164" class="code-line">実例: Mac の外部ディスプレイが映らない問題の解決</h2><p data-line="166" class="code-line"><code>/ultra-debug</code> の有無で大きく調査報告の質が変わった事例を一つ紹介します。</p><p data-line="168" class="code-line">Macbook に接続している外部ディスプレイがある日突然映らなくなり、その原因を Claude Code に尋ねました。</p><table data-line="170" class="code-line"><thead data-line="170" class="code-line"><tr data-line="170" class="code-line"><th>
</th><th>AI の回答内容</th>
<th>解決策</th>
<th>人の手間</th>
</tr></thead><tbody data-line="172" class="code-line"><tr data-line="172" class="code-line"><td><code>/ultra-debug</code> 無し</td>
<td>「ケーブルを変える」「再起動」「NVRAM のリセット」など一般的な対処法を羅列するだけ</td>
<td>不明</td>
<td>5 往復して進展無し</td>
</tr><tr data-line="173" class="code-line"><td><code>/ultra-debug</code> あり</td>
<td>macOS アップデートによるファームウェア変更が原因で USB4 の帯域を超過していることを、検証可能な証拠とセットで突き止めた</td>
<td>HDMI 接続で回避</td>
<td>最初の 1 回の指示だけ</td>
</tr></tbody></table><p data-line="176" class="code-line"><code>/ultra-debug</code> を使った結果、<strong>より少ない手間で、遥かに信頼度が高い調査結果</strong>を得ることができました。その時のレポート全文が以下です。</p><p data-line="178" class="code-line"><a href="https://github.com/swen128/claude-plugins/blob/27b2b13ce4ff68d088e9d2f4073ce8dd274330e1/ultra-debug/examples/ultra-debug-report.md" class="c5" target="_blank" rel="nofollow noopener noreferrer">https://github.com/swen128/claude-plugins/blob/27b2b13ce4ff68d088e9d2f4073ce8dd274330e1/ultra-debug/examples/ultra-debug-report.md</a></p><p data-line="180" class="code-line">このレポートに含まれているのは、最終的な答えだけではありません。どのような仮説を検討して、それぞれがどの証拠によって支持/否定されるのかを必ず示すルールになっています。そのため、根拠の薄い低質な報告はまず上がってきません。</p><p data-line="182" class="code-line">また、調査した具体的なファイルパスやコマンドなどが証拠の中に含まれているので、人間が最終的な判断をするための材料が揃った状態になります。</p><h2 id="agent-teams-%E3%82%92%E4%BD%BF%E3%81%86%E5%88%A9%E7%82%B9" data-line="184" class="code-line">Agent Teams を使う利点</h2><p data-line="186" class="code-line"><code>/ultra-debug</code> は Agent Teams に依存した作りになっています。ただの subagent ではなく Teams を使うのは、<strong>チームメイトがコンテキストを保持したまま複数ラウンドのやり取りができる</strong>ためです。</p><p data-line="188" class="code-line">通常の subagent は結果を返したら終了します<sup class="footnote-ref"><a href="#fn-7c87-1" id="fnref-7c87-1">[1]</a></sup>。レビュー結果を受けて再調査させたい場合、新しい subagent を起動することになりますが、前回の調査コンテキストが無いため、コマンドの再実行やログの再解析からやり直す必要があります。</p><p data-line="217" class="code-line">一方で Agent Teams なら、debugger は調査を終えた後 idle 状態で待機しています。その後またメッセージが送られてくると、最初のコンテキストを保持したまま再調査にすぐ取り掛かることができます。</p><section class="footnotes">脚注<ol class="footnotes-list"><li id="fn-7c87-1" class="footnote-item">
<p data-line="238" class="code-line"><code>Agent</code> ツールの <code>resume</code> 引数を使えば subagent のコンテキストを引き継ぐことは可能です。ただし Agent Teams では debugger 同士が直接メッセージを送り合えるため、ある debugger の発見を別の debugger の調査に役立てるなど、追加の利点があります。 <a href="#fnref-7c87-1" class="footnote-backref">↩︎</a></p>
</li>
</ol></section></div><div><div class="SendBadgeCta_content__FGxIx"><p>バッジを贈って著者を応援しよう</p><p class="Paragraph_common__yRSrj Paragraph_sidenote-sm__zfJpo">バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。</p></div>
</div>]]></description>
      <link>https://zenn.dev/dinii/articles/debugging-is-solved</link>
      <guid>https://zenn.dev/dinii/articles/debugging-is-solved</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Gone (Almost) Phishin’]]></title>
      <description><![CDATA[<p class="wp-block-paragraph">This is a little embarrassing to share, but I’d rather someone else be able to spot a dangerous scam before they fall for it. So, here goes.</p>
<p class="wp-block-paragraph">One evening last month, my Apple Watch, iPhone, and Mac all lit up with a message prompting me to reset my password<em>.</em> This came out of nowhere; I hadn’t done anything to elicit it. I even had <a href="https://support.apple.com/en-us/105120">Lockdown Mode</a> running on all my devices. It didn’t matter. Someone was spamming Apple’s legitimate password reset flow against my account—a technique <a href="https://krebsonsecurity.com/2024/03/recent-mfa-bombing-attacks-targeting-apple-users/">Krebs documented back in 2024</a>. I dismissed the prompts, but the stage was set.</p>
<p class="wp-block-paragraph">What made the attack impressive was the next move: The scammers actually contacted Apple Support themselves, pretending to be me, and opened a real case claiming I’d lost my phone and needed to update my number. That generated a real case ID, and triggered real Apple emails to my inbox, <em>properly signed</em>, from Apple’s actual servers. These were legitimate; no filter on earth could have caught them.</p>
<figure class="wp-block-image size-large"><img data-recalc-dims="1" width="604" height="587" data-attachment-id="151420" data-permalink="https://ma.tt/2026/03/gone-almost-phishin/cleanshot-2026-02-07-at-19-36-312x-2/" data-orig-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?fit=2146%2C2088&amp;quality=80&amp;ssl=1" data-orig-size="2146,2088" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="CleanShot 2026-02-07 at 19.36.31@2x" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?fit=761%2C740&amp;quality=80&amp;ssl=1" data-large-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?fit=604%2C587&amp;quality=80&amp;ssl=1" src="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1024x996.png?resize=604%2C587&amp;quality=80&amp;ssl=1" alt="" class="wp-image-151420" srcset="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=1024%2C996&amp;quality=80&amp;ssl=1 1024w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=195%2C190&amp;quality=80&amp;ssl=1 195w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=761%2C740&amp;quality=80&amp;ssl=1 761w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=768%2C747&amp;quality=80&amp;ssl=1 768w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=1536%2C1494&amp;quality=80&amp;ssl=1 1536w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=2048%2C1993&amp;quality=80&amp;ssl=1 2048w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?resize=473%2C460&amp;quality=80&amp;ssl=1 473w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?w=1208&amp;quality=80 1208w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-19.36.31%402x-1-1.png?w=1812&amp;quality=80 1812w" sizes="(max-width: 604px) 100vw, 604px" /></figure><p class="wp-block-paragraph">Then “Alexander from Apple Support” called. He was calm, knowledgeable, and <em>careful</em>. His first moves were solid security advice: check your account, verify nothing’s changed, consider updating your password. He was so good that I actually thanked him for being excellent at his job.</p>
<p class="wp-block-paragraph">That, of course, was when he moved into the next phase of the attack.</p>
<p class="wp-block-paragraph">He texted me a link to review and cancel the “pending request.” The site, audit-apple.com, was a pixel-perfect Apple replica, and displayed the exact case ID from the real emails I’d just received. There was even a fake chat transcript of the scammers’ actual conversation with Apple, presented back to me as evidence of the attack against my account. At the bottom of the page was a Sign in with Apple button that he told me to use.</p>
<figure data-carousel-extra="{&quot;blog_id&quot;:1,&quot;permalink&quot;:&quot;https://ma.tt/2026/03/gone-almost-phishin/&quot;}" class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><figure class="wp-block-image size-large"><img data-recalc-dims="1" width="604" height="395" data-attachment-id="151411" data-permalink="https://ma.tt/cleanshot-2026-02-07-at-18-14-372x/" data-orig-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?fit=2560%2C1674&amp;quality=80&amp;ssl=1" data-orig-size="2560,1674" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="CleanShot 2026-02-07 at 18.14.37@2x" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?fit=840%2C549&amp;quality=80&amp;ssl=1" data-large-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?fit=604%2C395&amp;quality=80&amp;ssl=1" data-id="151411" src="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-1024x670.png?resize=604%2C395&amp;quality=80&amp;ssl=1" alt="" class="wp-image-151411" srcset="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=1024%2C670&amp;quality=80&amp;ssl=1 1024w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=840%2C549&amp;quality=80&amp;ssl=1 840w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=195%2C128&amp;quality=80&amp;ssl=1 195w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=768%2C502&amp;quality=80&amp;ssl=1 768w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=1536%2C1004&amp;quality=80&amp;ssl=1 1536w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=2048%2C1339&amp;quality=80&amp;ssl=1 2048w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?resize=704%2C460&amp;quality=80&amp;ssl=1 704w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?w=1208&amp;quality=80 1208w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.14.37%402x-scaled.png?w=1812&amp;quality=80 1812w" sizes="(max-width: 604px) 100vw, 604px" /></figure><figure class="wp-block-image size-large"><img data-recalc-dims="1" width="604" height="418" data-attachment-id="151412" data-permalink="https://ma.tt/cleanshot-2026-02-07-at-18-08-362x/" data-orig-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?fit=2356%2C1628&amp;quality=80&amp;ssl=1" data-orig-size="2356,1628" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="CleanShot 2026-02-07 at 18.08.36@2x" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?fit=840%2C580&amp;quality=80&amp;ssl=1" data-large-file="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?fit=604%2C418&amp;quality=80&amp;ssl=1" data-id="151412" src="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x-1024x708.png?resize=604%2C418&amp;quality=80&amp;ssl=1" alt="" class="wp-image-151412" srcset="https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=1024%2C708&amp;quality=80&amp;ssl=1 1024w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=840%2C580&amp;quality=80&amp;ssl=1 840w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=195%2C135&amp;quality=80&amp;ssl=1 195w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=768%2C531&amp;quality=80&amp;ssl=1 768w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=1536%2C1061&amp;quality=80&amp;ssl=1 1536w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=2048%2C1415&amp;quality=80&amp;ssl=1 2048w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?resize=666%2C460&amp;quality=80&amp;ssl=1 666w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?w=1208&amp;quality=80 1208w, https://i0.wp.com/ma.tt/files/2026/03/CleanShot-2026-02-07-at-18.08.36%402x.png?w=1812&amp;quality=80 1812w" sizes="(max-width: 604px) 100vw, 604px" /></figure></figure><p class="wp-block-paragraph">I started poking at the page and noticed I could enter any case ID and get the same result. Nothing was being validated. It was all theater.</p>
<p class="wp-block-paragraph">“This is really good,” I told Alexander. “This is obviously phishing. So tell me about the scam.”</p>
<p class="wp-block-paragraph">Silence. *Click*.</p>
<p class="wp-block-paragraph">Once I’d suspected what was happening, I’d started recording the call, so I was able to save a good chunk of it, which Jamie Marsland used to make a video about the encounter. You can hear for yourself exactly how convincing “Alexander” was.</p>
<p class="wp-block-paragraph">So let my almost-disaster help you avoid your own. Remember these rules.</p>
<ul class="wp-block-list"><li><strong>Don’t approve any password-reset prompts</strong>—those are the first part of the attack. Do not pass Go, just head directly to your Apple ID settings. </li>
<li><strong>Apple will</strong> <strong><em>never</em></strong> <strong>call you first.</strong> </li>
<li>When you get an email from Apple—or, really, anyone telling you to complete a digital security measure—<strong>check the URL</strong> they’re trying to send you to. Apple Support lives on apple.com and getsupport.apple.com, nowhere else.</li>
</ul><p class="wp-block-paragraph">After all, the best protection is knowing what this looks like before it happens.</p>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"><iframe class="youtube-player c1" width="604" height="340" src="https://www.youtube.com/embed/deeNAGzVOY0?version=3&amp;rel=1&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;fs=1&amp;hl=en-US&amp;autohide=2&amp;wmode=transparent" allowfullscreen="allowfullscreen" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox">[embedded content]</iframe></div>
</figure>
<div id="jp-relatedposts" class="jp-relatedposts">
<h3 class="jp-relatedposts-headline"><em>Related</em></h3>
</div>]]></description>
      <link>https://ma.tt/2026/03/gone-almost-phishin/</link>
      <guid>https://ma.tt/2026/03/gone-almost-phishin/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[GitHub - LionyxML/emacs-solo: A Pure Emacs (no external packages) IDE like configuration.]]></title>
      <description><![CDATA[<div id="readme" class="org" data-path="README.org"><article class="markdown-body entry-content container-lg" itemprop="text"><p align="center" dir="auto">
<a target="_blank" rel="noopener noreferrer" href="doc/emacs-solo-logo.png"><img src="doc/emacs-solo-logo.png" alt="Project Logo" width="300" style="max-width: 100%;"></a>
<br>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/10f65b9b1adf062f69614aa18b6d3295f2012f9ccb45315c3e05c6ea23b13478/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456d6163732d33302532422d677265656e2e737667"><img src="https://camo.githubusercontent.com/10f65b9b1adf062f69614aa18b6d3295f2012f9ccb45315c3e05c6ea23b13478/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f456d6163732d33302532422d677265656e2e737667" alt="Emacs 30+" data-canonical-src="https://img.shields.io/badge/Emacs-30%2B-green.svg" style="max-width: 100%;"></a>
<a target="_blank" rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/48bf9b56d44f38db53ce21294cf0b9487d0a3734ab3ba1fe4c69858ae20db2c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d626c75652e737667"><img src="https://camo.githubusercontent.com/48bf9b56d44f38db53ce21294cf0b9487d0a3734ab3ba1fe4c69858ae20db2c1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d626c75652e737667" alt="GPLv3 License" data-canonical-src="https://img.shields.io/badge/License-GPLv3-blue.svg" style="max-width: 100%;"></a>
</p>
<p align="center" dir="auto">
A <em>fast</em>, <em>powerful</em> and <em>modular</em> Emacs configuration that favors built-in functionality over third-party packages.
</p>
<p align="center" dir="auto">
<a href="#obligatory-screenshots"><strong>Screenshots</strong></a> ·
<a href="#as-seen-on-system-crafters"><strong>System Crafters Demo</strong></a> ·
<a href="#minimum-emacs-version"><strong>Emacs Version</strong></a> ·
<a href="#optional-dependencies"><strong>Optional Dependencies</strong></a> ·
<a href="#installation"><strong>Installation</strong></a> ·
<a href="#disclaimer"><strong>Disclaimer</strong></a> ·
<a href="#how-do-i"><strong>FAQ</strong></a>
</p>
<hr>
<div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">Emacs Solo</h1><a id="user-content-emacs-solo" class="anchor" aria-label="Permalink: Emacs Solo" href="#emacs-solo"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This is what you see as soon as you start Emacs:</p>
<div class="highlight highlight-source-emacs-lisp notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="███████╗███╗   ███╗ █████╗  ██████╗███████╗    ███████╗ ██████╗ ██╗      ██████╗
██╔════╝████╗ ████║██╔══██╗██╔════╝██╔════╝    ██╔════╝██╔═══██╗██║     ██╔═══██╗
█████╗  ██╔████╔██║███████║██║     ███████╗    ███████╗██║   ██║██║     ██║   ██║
██╔══╝  ██║╚██╔╝██║██╔══██║██║     ╚════██║    ╚════██║██║   ██║██║     ██║   ██║
███████╗██║ ╚═╝ ██║██║  ██║╚██████╗███████║    ███████║╚██████╔╝███████╗╚██████╔╝
╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝

  Loading time : 0.172725 seconds
  Packages     : 0"><pre>███████╗███╗   ███╗ █████╗  ██████╗███████╗    ███████╗ ██████╗ ██╗      ██████╗
██╔════╝████╗ ████║██╔══██╗██╔════╝██╔════╝    ██╔════╝██╔═══██╗██║     ██╔═══██╗
█████╗  ██╔████╔██║███████║██║     ███████╗    ███████╗██║   ██║██║     ██║   ██║
██╔══╝  ██║╚██╔╝██║██╔══██║██║     ╚════██║    ╚════██║██║   ██║██║     ██║   ██║
███████╗██║ ╚═╝ ██║██║  ██║╚██████╗███████║    ███████║╚██████╔╝███████╗╚██████╔╝
╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝╚══════╝    ╚══════╝ ╚═════╝ ╚══════╝ ╚═════╝

  Loading time : <span class="pl-c1">0.172725</span> seconds
  Packages     : <span class="pl-c1">0</span></pre></div>
<p dir="auto">Emacs Solo is a configuration I use when I want to go back to the
  roots and challenge myself by using Emacs with only built-in features.</p>
<p dir="auto">It aims to be minimalist, at least in spirit. Yes, there are over 3000
  lines of code, but most of that comes from organizing things cleanly
  and building small, reusable modules. Compared to full-featured
  distributions, it’s still lean and focused.</p>
<p dir="auto">The configuration favors Emacs built-ins, configured my way. But when
  something essential is missing (like margin git gutters), a small,
  hacky workaround is always added.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Obligatory Screenshots</h2><a id="user-content-obligatory-screenshots" class="anchor" aria-label="Permalink: Obligatory Screenshots" href="#obligatory-screenshots"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Overall View:</h3><a id="user-content-overall-view" class="anchor" aria-label="Permalink: Overall View:" href="#overall-view"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-01-overall.png"><img src="doc/demo-01-overall.png" alt="doc/demo-01-overall.png" style="max-width: 100%;"></a></p>
<details open="">
<summary><div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">More screenshots here…</h3><a id="user-content-more-screenshots-here" class="anchor" aria-label="Permalink: More screenshots here…" href="#more-screenshots-here"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div></summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">iComplete (in buffer completion) + Flymake + Gutter:</h3><a id="user-content-icomplete-in-buffer-completion--flymake--gutter" class="anchor" aria-label="Permalink: iComplete (in buffer completion) + Flymake + Gutter:" href="#icomplete-in-buffer-completion--flymake--gutter"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-02-icomplete-flymake-gutter.png"><img src="doc/demo-02-icomplete-flymake-gutter.png" alt="doc/demo-02-icomplete-flymake-gutter.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Help Variable:</h3><a id="user-content-help-variable" class="anchor" aria-label="Permalink: Help Variable:" href="#help-variable"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-03-help-var.png"><img src="doc/demo-03-help-var.png" alt="doc/demo-03-help-var.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">iComplete Vertical:</h3><a id="user-content-icomplete-vertical" class="anchor" aria-label="Permalink: iComplete Vertical:" href="#icomplete-vertical"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-04-icomplete-vertical.png"><img src="doc/demo-04-icomplete-vertical.png" alt="doc/demo-04-icomplete-vertical.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Eshell:</h3><a id="user-content-eshell" class="anchor" aria-label="Permalink: Eshell:" href="#eshell"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-05-eshell.png"><img src="doc/demo-05-eshell.png" alt="doc/demo-05-eshell.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Dired + Gutter:</h3><a id="user-content-dired--gutter" class="anchor" aria-label="Permalink: Dired + Gutter:" href="#dired--gutter"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-06-dired-with-gutter.png"><img src="doc/demo-06-dired-with-gutter.png" alt="doc/demo-06-dired-with-gutter.png" style="max-width: 100%;"></a></p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-07-dired-with-gutter-2.png"><img src="doc/demo-07-dired-with-gutter-2.png" alt="doc/demo-07-dired-with-gutter-2.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Well behaved mode-line:</h3><a id="user-content-well-behaved-mode-line" class="anchor" aria-label="Permalink: Well behaved mode-line:" href="#well-behaved-mode-line"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-08-mode-line.png"><img src="doc/demo-08-mode-line.png" alt="doc/demo-08-mode-line.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">In Emacs Solo you find configurations for:</h3><a id="user-content-in-emacs-solo-you-find-configurations-for" class="anchor" aria-label="Permalink: In Emacs Solo you find configurations for:" href="#in-emacs-solo-you-find-configurations-for"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-09-single-init-file-with-sections.png"><img src="doc/demo-09-single-init-file-with-sections.png" alt="doc/demo-09-single-init-file-with-sections.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Emacs Solo also has a lot of extra mini-packages built-in:</h3><a id="user-content-emacs-solo-also-has-a-lot-of-extra-mini-packages-built-in" class="anchor" aria-label="Permalink: Emacs Solo also has a lot of extra mini-packages built-in:" href="#emacs-solo-also-has-a-lot-of-extra-mini-packages-built-in"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-10-single-init-file-with-sections-2.png"><img src="doc/demo-10-single-init-file-with-sections-2.png" alt="doc/demo-10-single-init-file-with-sections-2.png" style="max-width: 100%;"></a></p>
<p dir="auto">You can use <code>C-c d</code> or <code>M-x container-menu RET</code> to open a podman / docker
  container manager.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-12-container-management.png"><img src="doc/demo-12-container-management.png" alt="doc/demo-12-container-management.png" style="max-width: 100%;"></a></p>
<p dir="auto">Or you can use <code>C-c G</code> or <code>M-x gh-menu RET</code> to open a <code>gh</code> (github cli) UI:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-13-gh-1.png"><img src="doc/demo-13-gh-1.png" alt="doc/demo-13-gh-1.png" style="max-width: 100%;"></a></p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-13-gh-2.png"><img src="doc/demo-13-gh-2.png" alt="doc/demo-13-gh-2.png" style="max-width: 100%;"></a></p>
<p dir="auto">Emacs Solo also ships with some very cool themes!</p>
<p dir="auto">We’ve got:</p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Crafters</h4><a id="user-content-crafters" class="anchor" aria-label="Permalink: Crafters" href="#crafters"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-14-tema-crafters.png"><img src="doc/demo-14-tema-crafters.png" alt="doc/demo-14-tema-crafters.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Catppuccin</h4><a id="user-content-catppuccin" class="anchor" aria-label="Permalink: Catppuccin" href="#catppuccin"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-14-tema-catppuccin.png"><img src="doc/demo-14-tema-catppuccin.png" alt="doc/demo-14-tema-catppuccin.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">GITS</h4><a id="user-content-gits" class="anchor" aria-label="Permalink: GITS" href="#gits"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-14-tema-gits.png"><img src="doc/demo-14-tema-gits.png" alt="doc/demo-14-tema-gits.png" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h4 class="heading-element" dir="auto">Matrix</h4><a id="user-content-matrix" class="anchor" aria-label="Permalink: Matrix" href="#matrix"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="doc/demo-14-tema-matrix.png"><img src="doc/demo-14-tema-matrix.png" alt="doc/demo-14-tema-matrix.png" style="max-width: 100%;"></a></p>
<p dir="auto">And much more!</p>
</details>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">As seen on System Crafters!</h2><a id="user-content-as-seen-on-system-crafters" class="anchor" aria-label="Permalink: As seen on System Crafters!" href="#as-seen-on-system-crafters"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Also, check out the full demo of <code>Emacs Solo</code> in action, as seen on
  the System Crafters channel. In this video, David Wilson explores and
  learns from the configuration, showing how different settings and
  approaches are applied to create a more efficient and personalized
  Emacs setup.</p>
<p dir="auto"><a href="https://www.youtube.com/live/j_2QkCcf8zE?si=e8qvIFdyuV9j7d_y&amp;t=1433" rel="nofollow"><img src="https://camo.githubusercontent.com/290882a98f45c41696454dc6d102abc90efbd9f594b861752714d2908c2058b9/687474703a2f2f696d672e796f75747562652e636f6d2f76692f6a5f32516b436366387a452f302e6a7067" alt="http://img.youtube.com/vi/j_2QkCcf8zE/0.jpg" data-canonical-src="http://img.youtube.com/vi/j_2QkCcf8zE/0.jpg" style="max-width: 100%;"></a></p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Minimum Emacs Version</h2><a id="user-content-minimum-emacs-version" class="anchor" aria-label="Permalink: Minimum Emacs Version" href="#minimum-emacs-version"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Emacs Solo always requires the latest stable release of Emacs, which
  is currently: <code>30.1</code></p>
<p dir="auto">However, some bleeding-edge features may be tested as well. For those,
  you’ll need to compile Emacs from the master branch. I do my best to
  mark these features with the <code>EMACS-31</code> tag.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Optional Dependencies</h2><a id="user-content-optional-dependencies" class="anchor" aria-label="Permalink: Optional Dependencies" href="#optional-dependencies"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">It is recommended you have these programs in your system:</p>
<ul dir="auto">
  <li><code>ripgrep</code> (rg)
    <p dir="auto">This provides quicker project grep and xref navigation.</p>
    <p dir="auto">If you opt to use regular <code>grep</code>, reset the customization of variable
      <code>grep-command</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>ghostscript</code>
    <p dir="auto">This is necessary if you want to be able to use <code>doc-view</code> to see
      documents like PDFs.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>gls</code>
    <p dir="auto">MacOS comes with an implementation of <code>ls</code> that misses some nice
      switches from the gnu implementation (<code>gls</code> on homebrew). If you opt
      to use MacOS default <code>ls</code> you might need to change the
      <code>dired-listing-switches</code> variable.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>curl</code>
    <p dir="auto">Only needed if you’d like to upload text/images directly to 0x0.st
      site from Emacs Solo, by using either <code>emacs-solo/0x0-upload-text</code> or
      <code>emacs-solo/0x0-upload-file</code>.</p>
    <p dir="auto">Also used for <code>emacs-solo-weather</code>, <code>emacs-solo-rate</code> and
      <code>emacs-solo-how-in</code> (cheat.sh queries).</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>wget</code>
    <p dir="auto">If present on the system, emacs-solo <code>newsticker</code> config uses it
      instead of the internal fetcher.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>mpv</code>
    <p dir="auto">Only needed if you’d like to play videos directly from news in
      <code>newsticker</code>, play music from dired with dired music player <code>C-c m</code>,
      play something from a m3u file with <code>M-x m3u-visualizer-open-buffer</code>,
      listen to online radio with <code>C-c r</code>, or play YouTube results from
      <code>emacs-solo-yt</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>rsync</code>
    <p dir="auto">Only needed if you’d like to use <code>emacs-solo/dired-rsync-copy</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>ollama</code>
    <p dir="auto">Only needed if you’d like to use <code>emacs-solo/ollama-run-model</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>gemini-cli</code>
    <p dir="auto">Only needed if you’d like to use <code>emacs-solo/gemini-chat</code>.</p>
  </li>
  <li><code>claude</code>
    <p dir="auto">Only needed if you’d like to use <code>emacs-solo/claude-chat</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>khard</code>
    <p dir="auto">Only needed if you’d like to use <code>emacs-solo/khard-...</code> functions.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>yt-dlp</code>
    <p dir="auto">Only needed if you’d like to use <code>youtube-search-async</code> from
      <code>emacs-solo-yt</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>gh</code> (GitHub CLI)
    <p dir="auto">Only needed if you’d like to use the GitHub interface from
      <code>emacs-solo-gh</code> (PRs, issues, notifications).</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>docker</code> / <code>podman</code>
    <p dir="auto">Only needed if you’d like to use the container management UI from
      <code>emacs-solo-container</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>biome</code> / <code>prettier</code> / <code>shfmt</code>
    <p dir="auto">Only needed if you’d like to use the format-on-save feature from
      <code>emacs-solo-formatter</code>.  The formatter is resolved per-project
      (local install preferred over global).</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>eslint</code>
    <p dir="auto">Only needed if you’d like to use the Flymake ESLint backend from
      <code>emacs-solo-flymake-eslint</code>.</p>
  </li>
</ul>
<ul dir="auto">
  <li><code>rassumfrassum</code>
    <p dir="auto">Only needed if you’d like to use multiple LSP servers per buffer.</p>
  </li>
</ul>
<p dir="auto">In order to proper copy/paste from terminals (TUI), you need:</p>
<ul dir="auto">
  <li><code>pbcopy/pbpaste</code> (macOS)</li>
  <li><code>clip.exe/powershell.exe</code> (WSL)</li>
  <li><code>wl-copy/wl-paste</code> (Linux with Wayland)</li>
  <li><code>xclip</code> (Linux with Xorg)</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Installation</h2><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Clone this repository into a directory of your liking and run Emacs
  with:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="emacs --init-directory=YOUR_DIR"><pre>emacs --init-directory=YOUR_DIR</pre></div>
<p dir="auto">You can also simply copy <b>init.el</b>, <b>early-init.el</b> and the <b>lisp/</b>
  directory into any folder and issue the same command as above.</p>
<p dir="auto">And that’s it, happy hacking! 🐂</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Project Structure</h2><a id="user-content-project-structure" class="anchor" aria-label="Permalink: Project Structure" href="#project-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The configuration is split into two layers:</p>
<ul dir="auto">
  <li><code>init.el</code> / <code>early-init.el</code> — core configuration using Emacs built-ins.</li>
  <li><code>lisp/</code> — self-contained modules loaded via <code>require</code> at the end of
    <code>init.el</code>.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Disclaimer</h2><a id="user-content-disclaimer" class="anchor" aria-label="Permalink: Disclaimer" href="#disclaimer"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">I’m happy to share this configuration with a catchy name, and I’d be
  genuinely delighted if you find it useful. 🙂</p>
<p dir="auto">However, this is <b>not</b> intended to be a distribution. This means I may
  not cover every user’s needs, nor will I accept every contribution
  that pushes it in that direction. I use this configuration daily for
  both personal and professional work, and like any custom setup, it
  reflects my own preferences.</p>
<p dir="auto">For example, this config does not include Python-specific settings,
  whether for Eglot or Tree-sitter. Since this is a real working setup
  and I’m not currently using Python, its absence might seem like an
  oversight.</p>
<p dir="auto">If you’d like to add your own modifications while staying up to date
  with Emacs Solo, simply create a <code>private.el</code> file in the same directory
  as <code>init.el</code>. A hook is already in place to load this private file after
  Emacs initializes.</p>
<p dir="auto">Of course, you can also fork it! (please do 😊)</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">How do I…</h2><a id="user-content-how-do-i" class="anchor" aria-label="Permalink: How do I…" href="#how-do-i"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A FAQ-like section of common questions on how to do X with only Emacs Solo.</p>
<details open="">
<summary><div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">So, how do I…</h3><a id="user-content-so-how-do-i" class="anchor" aria-label="Permalink: So, how do I…" href="#so-how-do-i"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div></summary>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">1.) Copy the current word under cursor?</h3><a id="user-content-1-copy-the-current-word-under-cursor" class="anchor" aria-label="Permalink: 1.) Copy the current word under cursor?" href="#1-copy-the-current-word-under-cursor"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The usual answer is <b>M-b</b> to go back to the beginning of the
  word. <b>C-M-SPC</b> to expand the selection to the end of the word and <b>M-w</b>.</p>
<p dir="auto"><b>Custom Emacs Solo Solution</b>: Use the isearch way to search a word (it has
  better completion than C-M-SPC), like <b>M-s M-.</b> you can now just <b>M-w</b>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">2.) Edit multiple search entries at once?</h3><a id="user-content-2-edit-multiple-search-entries-at-once" class="anchor" aria-label="Permalink: 2.) Edit multiple search entries at once?" href="#2-edit-multiple-search-entries-at-once"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<pre lang="text">Original problem: I usually consult-outline, then embark-collect and wgrep...
</pre>
<p dir="auto">You can start by using <b>occur</b>, or using <b>isearch</b> and then moving to occur.</p>
<p dir="auto">Next start the edit mode of the occur buffer with <b>e</b>.</p>
<p dir="auto">Make your changes, apply it with <b>C-c C-c</b></p>
<p dir="auto">From Emacs 30.1 onward you can also use the combo:
  <code>replace-regexp-as-diff</code> for replacements in a single buffer,
  <code>multi-replace-regexp-as-diff</code> for multiple buffers, and
  <code>dired-do-replace-regexp-as-diff</code> to perform replace-regexp-as-diff</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">3.) Edit multiple search entries between several files at once?</h3><a id="user-content-3-edit-multiple-search-entries-between-several-files-at-once" class="anchor" aria-label="Permalink: 3.) Edit multiple search entries between several files at once?" href="#3-edit-multiple-search-entries-between-several-files-at-once"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<pre lang="text">Original problem: I usually consult-grep, then use embark collect and wgrep...
</pre>
<p dir="auto">Open dired on the root folder of where you search will happen. Mark
  some files and or folders with <b>m</b>.</p>
<p dir="auto">Use <code>dired-do-query-replace-regexp</code> or in a dired buffer hit <code>Q</code>.</p>
<p dir="auto">Confirm it all or one by one, use <b>?</b> to check the options.</p>
<p dir="auto">From Emacs 30.1 onward you can also use the combo:
  <code>replace-regexp-as-diff</code> for replacements in a single buffer,
  <code>multi-replace-regexp-as-diff</code> for multiple buffers, and
  <code>dired-do-replace-regexp-as-diff</code> to perform replace-regexp-as-diff</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">4.) Read news, like with elfeed?</h3><a id="user-content-4-read-news-like-with-elfeed" class="anchor" aria-label="Permalink: 4.) Read news, like with elfeed?" href="#4-read-news-like-with-elfeed"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">You have two built-in options on Emacs.</p>
<ul dir="auto">
  <li><code>M-x gnus</code></li>
  <li><code>M-x newsticker-treeview</code></li>
</ul>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">5.) How do I see logs and their diffs?</h3><a id="user-content-5-how-do-i-see-logs-and-their-diffs" class="anchor" aria-label="Permalink: 5.) How do I see logs and their diffs?" href="#5-how-do-i-see-logs-and-their-diffs"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>C-x v L</code> on a file inside your version controlled file. And over the
  line you have the commit, press <code>d</code> for diffing.</p>
<p dir="auto">If you wanna diff a range, mark the lines starting with <code>C-SPC</code> on the
  first line of the range, and again <code>C-SPC</code> in the last line of the range
  (the content of what you want must be selected, if the cursor is on
  first column of the line it won’t be included), now use <code>d</code> to diff.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">6.) How do I revert a hunk?</h3><a id="user-content-6-how-do-i-revert-a-hunk" class="anchor" aria-label="Permalink: 6.) How do I revert a hunk?" href="#6-how-do-i-revert-a-hunk"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>C-x v =</code> will open the diff panel for the current file, restrict it to
  the hunk you’d like to revert with <code>r</code>, revert the direction of the diff
  with <code>R</code> and apply the diff with <code>C-c C-a</code>.</p>
<p dir="auto">From Emacs 31, we also have <code>C-c M-r</code> (<code>diff-revert-and-kill</code>), when on
  buffers generated by <code>C-x v =</code> and <code>C-x v D</code>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">7.) Use (neo)vi(m) keybindings (aka Evil keybindings)?</h3><a id="user-content-7-use-neovim-keybindings-aka-evil-keybindings" class="anchor" aria-label="Permalink: 7.) Use (neo)vi(m) keybindings (aka Evil keybindings)?" href="#7-use-neovim-keybindings-aka-evil-keybindings"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Emacs comes with <code>viper</code> which is a <code>vi</code> emulator. This means a lot of
  modern editing capabilities are missing.</p>
<p dir="auto">Take a look at the <code>use-package Emacs Solo-viper-extensions</code> section of the
  <code>init.el</code> file. Emacs Solo extends viper mode to include a bunch of more
  modern <code>evil-like</code> bindings.</p>
<p dir="auto">Just give it a try ;) <code>M-x viper-mode</code></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">8.) Temporarily highlight some word?</h3><a id="user-content-8-temporarily-highlight-some-word" class="anchor" aria-label="Permalink: 8.) Temporarily highlight some word?" href="#8-temporarily-highlight-some-word"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use the powers of <code>highlight-regexp</code>! Over a word you want to make
  highlighted use <code>M-s h .</code></p>
<p dir="auto">You can repeat it to other words and Emacs will handle different
  colors for you.</p>
<p dir="auto">To remove a highlight use <code>M-s h u</code> and select the highlighted regexp on
  the list.</p>
<p dir="auto">Find out about more options regarding highlighting with <code>M-s h ?</code>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">9.) Know what is changed when closing Emacs or several files?</h3><a id="user-content-9-know-what-is-changed-when-closing-emacs-or-several-files" class="anchor" aria-label="Permalink: 9.) Know what is changed when closing Emacs or several files?" href="#9-know-what-is-changed-when-closing-emacs-or-several-files"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">It is a common thing trying to close Emacs with <code>C-x C-c</code> just to find
  out one of your buffers has some modification and now Emacs asks if
  you’d like to save, override, etc.</p>
<p dir="auto">Emacs Solo provides the extra option <code>d</code>, which will generate a diff of
  the current file being asked to take action, so you can see if saving
  is needed.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">10.) Show/Hide (toggle) hidden files in Dired?</h3><a id="user-content-10-showhide-toggle-hidden-files-in-dired" class="anchor" aria-label="Permalink: 10.) Show/Hide (toggle) hidden files in Dired?" href="#10-showhide-toggle-hidden-files-in-dired"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>dired-omit-mode</code>, which you can toggle with <code>C-x M-o</code>. Notice that
  this mode uses the regular expression defined in the <code>dired-omit-files</code>
  variable. Emacs Solo already customizes this to ignore files matching
  <code>^\\.</code></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">11.) Open multiple terms/shells?</h3><a id="user-content-11-open-multiple-termsshells" class="anchor" aria-label="Permalink: 11.) Open multiple terms/shells?" href="#11-open-multiple-termsshells"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Ever felt the need of some <code>multi-term</code> package on Emacs? Well, you
  don’t really need it, at least not with the internal implementations
  of terminals and <code>eshell</code>.</p>
<p dir="auto">Just use the <code>C-u</code> universal argument command before calling your
  term/shell, like: <code>C-u M-x eshell</code> or <code>C-u C-x p e</code> or <code>C-u M-x term</code>, and
  so on.</p>
<p dir="auto">Now you have another instance of your term to work with, repeat this
  pattern if you need more instances.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">12.) How do I select a single hunk out of many?</h3><a id="user-content-12-how-do-i-select-a-single-hunk-out-of-many" class="anchor" aria-label="Permalink: 12.) How do I select a single hunk out of many?" href="#12-how-do-i-select-a-single-hunk-out-of-many"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">From Emacs 31, we have after <code>C-x v =</code> a new <code>C-c RET n</code>
  (<code>diff-delete-other-hunks</code>) option to do so.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">13.) How do I edit commit messages?</h3><a id="user-content-13-how-do-i-edit-commit-messages" class="anchor" aria-label="Permalink: 13.) How do I edit commit messages?" href="#13-how-do-i-edit-commit-messages"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">From <code>C-x v L</code>, you can press <code>e</code> and you’ll be editing the commit
  message. This is available from Emacs 31 onward.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">14.) How do I amend commits?</h3><a id="user-content-14-how-do-i-amend-commits" class="anchor" aria-label="Permalink: 14.) How do I amend commits?" href="#14-how-do-i-amend-commits"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">From <code>C-x v v</code>, you can press <code>C-c C-e</code> and you’ll be on ‘amend’ mode.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">15.) Zoom fonts</h3><a id="user-content-15-zoom-fonts" class="anchor" aria-label="Permalink: 15.) Zoom fonts" href="#15-zoom-fonts"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Only the current buffer:</p>
<p dir="auto"><code>C-x C--</code>
  <code>C-x C-+</code> / <code>C-x C-=</code>
  <code>C-x C-0</code></p>
<p dir="auto">The whole interface:</p>
<p dir="auto"><code>C-x C-M--</code>
  <code>C-x C-M-+</code> / <code>C-x C-M-</code>
  <code>C-x C-M-0</code></p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">16.) Visit an URL</h3><a id="user-content-16-visit-an-url" class="anchor" aria-label="Permalink: 16.) Visit an URL" href="#16-visit-an-url"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">With <code>global-goto-address-mode</code> turned on, you can <code>C-c RET</code> over a link
  to open it on your default browser.</p>
<p dir="auto"><code>C-u C-c RET</code> will open it on the secondary browser, recommended:</p>
<p dir="auto">Emacs Solo defaults:</p>
<div class="highlight highlight-source-emacs-lisp notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="(setq global-goto-address-mode t)
(setq browse-url-secondary-browser-function 'eww-browse-url)"><pre>(<span class="pl-k">setq</span> global-goto-address-mode <span class="pl-c1">t</span>)
(<span class="pl-k">setq</span> browse-url-secondary-browser-function <span class="pl-c1">'eww-browse-url</span>)</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">17.) Increase/Decrease the resolution of PDFs</h3><a id="user-content-17-increasedecrease-the-resolution-of-pdfs" class="anchor" aria-label="Permalink: 17.) Increase/Decrease the resolution of PDFs" href="#17-increasedecrease-the-resolution-of-pdfs"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The <code>doc-view-resolution</code> variable is the way to go.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">18.) Open an URL under point</h3><a id="user-content-18-open-an-url-under-point" class="anchor" aria-label="Permalink: 18.) Open an URL under point" href="#18-open-an-url-under-point"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Given <code>global-goto-address-mode</code> is set to <code>t</code>, we can <code>C-c RET</code> to url
  under point. This will use your system default browser.</p>
<p dir="auto">If you’d like to use <code>EWW</code> and never leave Emacs, simply set
  <code>browse-url-secondary-browser-function</code> to <code>'eww-browse-url</code>. This way you
  can <code>C-u C-c RET</code>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">19.) Open a file when path is under point</h3><a id="user-content-19-open-a-file-when-path-is-under-point" class="anchor" aria-label="Permalink: 19.) Open a file when path is under point" href="#19-open-a-file-when-path-is-under-point"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use <code>C-x f</code> and then <code>M-n</code> to get the path under point fed to <code>file-find</code>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">20.) Kill buffer and close window</h3><a id="user-content-20-kill-buffer-and-close-window" class="anchor" aria-label="Permalink: 20.) Kill buffer and close window" href="#20-kill-buffer-and-close-window"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Usually <code>C-x k</code> kills a buffer, but it keeps the window opened. If you
  wish to kill and close window, use <code>C-x 4 0</code> (<code>kill-buffer-and-window</code>).</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">21.) Attach multiple files in message-mode?</h3><a id="user-content-21-attach-multiple-files-in-message-mode" class="anchor" aria-label="Permalink: 21.) Attach multiple files in message-mode?" href="#21-attach-multiple-files-in-message-mode"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When on <code>gnus</code> and composing a message, if you’d like to attach multiple
  files using dired, just split with dired <code>C-x 4 d</code>, use <code>M-x
  turn-on-gnus-dired-mode RET</code>, mark files with <code>m</code> and use <code>C-c RET C-a</code> to
  populate your composing buffer.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">22.) Use multiple LSP servers per buffer?</h3><a id="user-content-22-use-multiple-lsp-servers-per-buffer" class="anchor" aria-label="Permalink: 22.) Use multiple LSP servers per buffer?" href="#22-use-multiple-lsp-servers-per-buffer"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">For this you need to use an external LSP multiplexer, so Eglot can
  connect to it. Eglot’s author made his own implementation of such a
  program: <a href="https://github.com/joaotavora/rassumfrassum">https://github.com/joaotavora/rassumfrassum</a>.</p>
<p dir="auto">Basically <code>C-u M-x eglot</code> and enter <code>rass -- server1 [options] -- server2
  [options] --...</code>.</p>
<p dir="auto">You can read more about it in this blogpost:
  <a href="https://www.rahuljuliato.com/posts/eglot-rassumfrassum" rel="nofollow">https://www.rahuljuliato.com/posts/eglot-rassumfrassum</a>.</p>
</details>
</article></div>]]></description>
      <link>https://github.com/LionyxML/emacs-solo</link>
      <guid>https://github.com/LionyxML/emacs-solo</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[GitHub - pbakaus/impeccable: Claude + Cursor plugins that make your LLM of choice great at UX / frontend design.]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">Impeccable</h1><a id="user-content-impeccable" class="anchor" aria-label="Permalink: Impeccable" href="#impeccable"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The vocabulary you didn't know you needed. 1 skill, 17 commands, and curated anti-patterns for impeccable frontend design.</p>
<blockquote>
<p dir="auto"><strong>Quick start:</strong> Visit <a href="https://impeccable.style" rel="nofollow">impeccable.style</a> to download ready-to-use bundles.</p>
</blockquote>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Why Impeccable?</h2><a id="user-content-why-impeccable" class="anchor" aria-label="Permalink: Why Impeccable?" href="#why-impeccable"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Anthropic created <a href="https://github.com/anthropics/skills/tree/main/skills/frontend-design">frontend-design</a>, a skill that guides Claude toward better UI design. Impeccable builds on that foundation with deeper expertise and more control.</p>
<p dir="auto">Every LLM learned from the same generic templates. Without guidance, you get the same predictable mistakes: Inter font, purple gradients, cards nested in cards, gray text on colored backgrounds.</p>
<p dir="auto">Impeccable fights that bias with:</p>
<ul dir="auto">
<li><strong>An expanded skill</strong> with 7 domain-specific reference files (<a href="source/skills/frontend-design/">view source</a>)</li>
<li><strong>17 steering commands</strong> to audit, review, polish, distill, animate, and more</li>
<li><strong>Curated anti-patterns</strong> that explicitly tell the AI what NOT to do</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">What's Included</h2><a id="user-content-whats-included" class="anchor" aria-label="Permalink: What's Included" href="#whats-included"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">The Skill: frontend-design</h3><a id="user-content-the-skill-frontend-design" class="anchor" aria-label="Permalink: The Skill: frontend-design" href="#the-skill-frontend-design"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">A comprehensive design skill with 7 domain-specific references (<a href="source/skills/frontend-design/SKILL.md">view skill</a>):</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Reference</th>
<th>Covers</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="source/skills/frontend-design/reference/typography.md">typography</a></td>
<td>Type systems, font pairing, modular scales, OpenType</td>
</tr>
<tr>
<td><a href="source/skills/frontend-design/reference/color-and-contrast.md">color-and-contrast</a></td>
<td>OKLCH, tinted neutrals, dark mode, accessibility</td>
</tr>
<tr>
<td><a href="source/skills/frontend-design/reference/spatial-design.md">spatial-design</a></td>
<td>Spacing systems, grids, visual hierarchy</td>
</tr>
<tr>
<td><a href="source/skills/frontend-design/reference/motion-design.md">motion-design</a></td>
<td>Easing curves, staggering, reduced motion</td>
</tr>
<tr>
<td><a href="source/skills/frontend-design/reference/interaction-design.md">interaction-design</a></td>
<td>Forms, focus states, loading patterns</td>
</tr>
<tr>
<td><a href="source/skills/frontend-design/reference/responsive-design.md">responsive-design</a></td>
<td>Mobile-first, fluid design, container queries</td>
</tr>
<tr>
<td><a href="source/skills/frontend-design/reference/ux-writing.md">ux-writing</a></td>
<td>Button labels, error messages, empty states</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">17 Commands</h3><a id="user-content-17-commands" class="anchor" aria-label="Permalink: 17 Commands" href="#17-commands"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Command</th>
<th>What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>/teach-impeccable</code></td>
<td>One-time setup: gather design context, save to config</td>
</tr>
<tr>
<td><code>/audit</code></td>
<td>Run technical quality checks (a11y, performance, responsive)</td>
</tr>
<tr>
<td><code>/critique</code></td>
<td>UX design review: hierarchy, clarity, emotional resonance</td>
</tr>
<tr>
<td><code>/normalize</code></td>
<td>Align with design system standards</td>
</tr>
<tr>
<td><code>/polish</code></td>
<td>Final pass before shipping</td>
</tr>
<tr>
<td><code>/distill</code></td>
<td>Strip to essence</td>
</tr>
<tr>
<td><code>/clarify</code></td>
<td>Improve unclear UX copy</td>
</tr>
<tr>
<td><code>/optimize</code></td>
<td>Performance improvements</td>
</tr>
<tr>
<td><code>/harden</code></td>
<td>Error handling, i18n, edge cases</td>
</tr>
<tr>
<td><code>/animate</code></td>
<td>Add purposeful motion</td>
</tr>
<tr>
<td><code>/colorize</code></td>
<td>Introduce strategic color</td>
</tr>
<tr>
<td><code>/bolder</code></td>
<td>Amplify boring designs</td>
</tr>
<tr>
<td><code>/quieter</code></td>
<td>Tone down overly bold designs</td>
</tr>
<tr>
<td><code>/delight</code></td>
<td>Add moments of joy</td>
</tr>
<tr>
<td><code>/extract</code></td>
<td>Pull into reusable components</td>
</tr>
<tr>
<td><code>/adapt</code></td>
<td>Adapt for different devices</td>
</tr>
<tr>
<td><code>/onboard</code></td>
<td>Design onboarding flows</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Anti-Patterns</h3><a id="user-content-anti-patterns" class="anchor" aria-label="Permalink: Anti-Patterns" href="#anti-patterns"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The skill includes explicit guidance on what to avoid:</p>
<ul dir="auto">
<li>Don't use overused fonts (Arial, Inter, system defaults)</li>
<li>Don't use gray text on colored backgrounds</li>
<li>Don't use pure black/gray (always tint)</li>
<li>Don't wrap everything in cards or nest cards inside cards</li>
<li>Don't use bounce/elastic easing (feels dated)</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">See It In Action</h2><a id="user-content-see-it-in-action" class="anchor" aria-label="Permalink: See It In Action" href="#see-it-in-action"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Visit <a href="https://impeccable.style#casestudies" rel="nofollow">impeccable.style</a> to see before/after case studies of real projects transformed with Impeccable commands.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Installation</h2><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Option 1: Download from Website (Recommended)</h3><a id="user-content-option-1-download-from-website-recommended" class="anchor" aria-label="Permalink: Option 1: Download from Website (Recommended)" href="#option-1-download-from-website-recommended"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Visit <a href="https://impeccable.style" rel="nofollow">impeccable.style</a>, download the ZIP for your tool, and extract to your project.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Option 2: Copy from Repository</h3><a id="user-content-option-2-copy-from-repository" class="anchor" aria-label="Permalink: Option 2: Copy from Repository" href="#option-2-copy-from-repository"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Cursor:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cp -r dist/cursor/.cursor your-project/"><pre>cp -r dist/cursor/.cursor your-project/</pre></div>
<blockquote>
<p dir="auto"><strong>Note:</strong> Cursor skills require setup:</p>
<ol dir="auto">
<li>Switch to Nightly channel in Cursor Settings → Beta</li>
<li>Enable Agent Skills in Cursor Settings → Rules</li>
</ol>
<p dir="auto"><a href="https://cursor.com/docs/context/skills" rel="nofollow">Learn more about Cursor skills</a></p>
</blockquote>
<p dir="auto"><strong>Claude Code:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Project-specific
cp -r dist/claude-code/.claude your-project/

# Or global (applies to all projects)
cp -r dist/claude-code/.claude/* ~/.claude/"><pre><span class="pl-c"><span class="pl-c">#</span> Project-specific</span>
cp -r dist/claude-code/.claude your-project/

<span class="pl-c"><span class="pl-c">#</span> Or global (applies to all projects)</span>
cp -r dist/claude-code/.claude/<span class="pl-k">*</span> <span class="pl-k">~</span>/.claude/</pre></div>
<p dir="auto"><strong>Gemini CLI:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cp -r dist/gemini/.gemini your-project/"><pre>cp -r dist/gemini/.gemini your-project/</pre></div>
<blockquote>
<p dir="auto"><strong>Note:</strong> Gemini CLI skills require setup:</p>
<ol dir="auto">
<li>Install preview version: <code>npm i -g @google/gemini-cli@preview</code></li>
<li>Run <code>/settings</code> and enable "Skills"</li>
<li>Run <code>/skills list</code> to verify installation</li>
</ol>
<p dir="auto"><a href="https://geminicli.com/docs/cli/skills/" rel="nofollow">Learn more about Gemini CLI skills</a></p>
</blockquote>
<p dir="auto"><strong>Codex CLI:</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cp -r dist/codex/.codex/* ~/.codex/"><pre>cp -r dist/codex/.codex/<span class="pl-k">*</span> <span class="pl-k">~</span>/.codex/</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Usage</h2><a id="user-content-usage" class="anchor" aria-label="Permalink: Usage" href="#usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Once installed, use commands in your AI harness:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/audit           # Find issues
/normalize       # Fix inconsistencies
/polish          # Final cleanup
/distill         # Remove complexity"><pre class="notranslate"><code>/audit           # Find issues
/normalize       # Fix inconsistencies
/polish          # Final cleanup
/distill         # Remove complexity
</code></pre></div>
<p dir="auto">Most commands accept an optional argument to focus on a specific area:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/audit header
/polish checkout-form"><pre class="notranslate"><code>/audit header
/polish checkout-form
</code></pre></div>
<p dir="auto"><strong>Note:</strong> Codex CLI uses a different syntax: <code>/prompts:audit</code>, <code>/prompts:polish</code>, etc.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Supported Tools</h2><a id="user-content-supported-tools" class="anchor" aria-label="Permalink: Supported Tools" href="#supported-tools"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="https://cursor.com" rel="nofollow">Cursor</a></li>
<li><a href="https://claude.ai/code" rel="nofollow">Claude Code</a></li>
<li><a href="https://github.com/google-gemini/gemini-cli">Gemini CLI</a></li>
<li><a href="https://github.com/openai/codex">Codex CLI</a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Contributing</h2><a id="user-content-contributing" class="anchor" aria-label="Permalink: Contributing" href="#contributing"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">See <a href="DEVELOP.md">DEVELOP.md</a> for contributor guidelines and build instructions.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Apache 2.0. See <a href="LICENSE">LICENSE</a>.</p>
<p dir="auto">The frontend-design skill builds on <a href="https://github.com/anthropics/skills/tree/main/skills/frontend-design">Anthropic's original</a>. See <a href="NOTICE.md">NOTICE.md</a> for attribution.</p>
<hr>
<p dir="auto">Created by <a href="https://www.paulbakaus.com" rel="nofollow">Paul Bakaus</a></p>
</article></div>]]></description>
      <link>https://github.com/pbakaus/impeccable</link>
      <guid>https://github.com/pbakaus/impeccable</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Grammarly Is Offering ‘Expert’ AI Reviews From Your Favorite Authors—Dead or Alive (without their permission)]]></title>
      <description><![CDATA[<div class="AIContentWrapper-lBLcd bblOul"><div class="ArticlePageLedeBackground-bNmFvK eudZMI"><header class="SplitScreenContentHeaderWrapper-kYXvBM jbpCVU content-header article__content-header" data-testid="SplitScreenContentHeaderWrapper"><div class="GridWrapper-uulHE kCXnFV grid grid-items-2 grid-full-bleed grid-no-gap SplitScreenContentHeaderMain-klfmk fjqJXY with-divider-desktop with-divider-mobile inset" data-journey-hook="grid-wrapper"><div class="GridItem-bufwYC fVPmGe grid--item"><div class="SplitScreenContentHeaderTitleBlock-hlDbje eQqdJY"><div class="content-header-text"><div class="BaseText-fEwdHD SplitScreenContentHeaderDek-juwmcJ hieunh bFhTNF">The tool, offered by the recently-rebranded company Superhuman, gives feedback based on the work of famous dead and living writers—without their permission.</div></div></div></div><div class="GridItem-bufwYC fVPmGe grid--item"><div class="SplitScreenContentHeaderLeadWrapper-hSIObk hENeSt"><div data-testid="ContentHeaderLeadAsset" class="SplitScreenContentHeaderLedeBlock-gyTnpK bWrTPF"><picture class="ResponsiveImagePicture-jKunQM gjCCFj SplitScreenContentHeaderLede-dhVTZD jloyWy responsive-image"><source media="(max-width: 767px)" srcset="https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_120,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 120w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_240,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 240w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_320,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 320w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_640,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 640w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_960,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 960w" sizes="100vw" /><source media="(min-width: 768px)" srcset="https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_120,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 120w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_240,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 240w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_320,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 320w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_640,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 640w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_960,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 960w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_1280,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 1280w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_1600,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 1600w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_1920,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 1920w, https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_2240,c_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg 2240w" sizes="100vw" /><img alt="Logo for the AI text editing company Grammarly at the Grammarly AI Hub in Austin Texas March 11 2023." class="ResponsiveImageContainer-dkeESL cQPiWi responsive-image__image" src="https://media.wired.com/photos/69a72224fed0d8b129f5a806/master/w_2560%2Cc_limit/Grammarly-Making-LLMs-Based-on-Dead-Academics-Culture-1473977398.jpg" /></picture></div></div></div></div><div class="GridWrapper-uulHE dArhxS grid grid-margins grid-items-0 SplitScreenContentHeaderGrid-btvIAX ipcpCb align-end" data-journey-hook="grid-wrapper"><div class="GridItem-bufwYC khuCvB grid--item"><div class="CaptionWrapper-bpPcvW iDPSlt caption SplitScreenContentHeaderCaption-gPlPMN ikxKhH" data-testid="caption-wrapper">Photograph: Smith Collection/Getty Images</div></div></div></header></div></div><div data-attribute-verso-pattern="article-body" class="ArticlePageContentBackGround-eDdQYX jBrCot article-body__content"><div data-testid="action-bar-wrapper" class="ActionBarWrapperContent-eyqXkK edhert"><div class="ActionBarWrapperComponent-chDeHg dIFaKt"><div data-attr-viewport-monitor="" class="ActionBarWrapper-kJGqdz dwThYB viewport-monitor-anchor"><div data-attr-viewport-monitor="" class="ActionBarWrapper-kJGqdz klCXQy viewport-monitor-anchor"></div></div><div class="ArticlePageChunksContent-hsbblt lnfIPJ"><div data-testid="ArticlePageChunks" class="ArticlePageChunks-lfyGNk gEPfMM"><div class="GridWrapper-uulHE dCnZHU grid grid-margins grid-items-2 ArticlePageChunksGrid-kSknMg dSvDdx grid-layout--adrail narrow wide-adrail" data-journey-hook="grid-wrapper"><div class="GridItem-bufwYC kKTABR grid--item grid-layout__content"><div class="BodyWrapper-cuqCAc eujiPN body body__container article__body" data-journey-hook="client-content" data-testid="BodyWrapper"><figure data-testid="cne-audio-embed-figure" class="CneAudioEmbedFigure-cwqusU dGMPjV"><div data-testid="cne-audio-embed-container"></div></figure><div class="body__inner-container"><p>Do you have fond memories of being a teacher’s pet? Wish you could still get notes from your favorite <a href="https://www.wired.com/tag/college/">college</a> professor? Dream about some implacable voice of authority correcting your every <a href="https://www.wired.com/tag/creative-writing/">word choice</a> and punctuation mark? Well, great news: A certain software company has engineered a way to simulate criticism not just from bestselling authors and famous academics of our time, but also many who died decades ago—and the company evidently didn’t need permission from anybody to do it.</p><p class="paywall">Once relied upon only to proofread for correct grammar and spelling, the writing tool Grammarly has added a host of generative AI features over the past several years. In October, CEO Shishir Mehrotra announced that the overall company was rebranding as Superhuman to reflect a new suite of AI-powered products. However, the AI writing “partner” <a data-offer-url="https://superhuman.com/?utm_source=google-brand&amp;utm_medium=cpc&amp;utm_campaign=23178915355&amp;utm_content=780512411653&amp;utm_term=superhuman%20grammarly&amp;target=&amp;targetid=kwd-2436536756795&amp;adgroup=187069800403&amp;device=c&amp;matchtype=e&amp;placement=&amp;network=g&amp;extension=&amp;clickid=CjwKCAiAzZ_NBhAEEiwAMtqKy3fFbxRxKVCCXSB6WzTZR9JemlY7GEc8cxf499Iqxe20N4Plr28L-xoCA38QAvD_BwE&amp;gad_source=1&amp;gad_campaignid=23178915355&amp;gbraid=0AAAABBoNLYwg_Uf8W-54O15mVdpq1PfDK&amp;gclid=CjwKCAiAzZ_NBhAEEiwAMtqKy3fFbxRxKVCCXSB6WzTZR9JemlY7GEc8cxf499Iqxe20N4Plr28L-xoCA38QAvD_BwE" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://superhuman.com/?utm_source=google-brand&amp;utm_medium=cpc&amp;utm_campaign=23178915355&amp;utm_content=780512411653&amp;utm_term=superhuman%20grammarly&amp;target=&amp;targetid=kwd-2436536756795&amp;adgroup=187069800403&amp;device=c&amp;matchtype=e&amp;placement=&amp;network=g&amp;extension=&amp;clickid=CjwKCAiAzZ_NBhAEEiwAMtqKy3fFbxRxKVCCXSB6WzTZR9JemlY7GEc8cxf499Iqxe20N4Plr28L-xoCA38QAvD_BwE&amp;gad_source=1&amp;gad_campaignid=23178915355&amp;gbraid=0AAAABBoNLYwg_Uf8W-54O15mVdpq1PfDK&amp;gclid=CjwKCAiAzZ_NBhAEEiwAMtqKy3fFbxRxKVCCXSB6WzTZR9JemlY7GEc8cxf499Iqxe20N4Plr28L-xoCA38QAvD_BwE&quot;}" href="https://superhuman.com/?utm_source=google-brand&amp;utm_medium=cpc&amp;utm_campaign=23178915355&amp;utm_content=780512411653&amp;utm_term=superhuman%20grammarly&amp;target=&amp;targetid=kwd-2436536756795&amp;adgroup=187069800403&amp;device=c&amp;matchtype=e&amp;placement=&amp;network=g&amp;extension=&amp;clickid=CjwKCAiAzZ_NBhAEEiwAMtqKy3fFbxRxKVCCXSB6WzTZR9JemlY7GEc8cxf499Iqxe20N4Plr28L-xoCA38QAvD_BwE&amp;gad_source=1&amp;gad_campaignid=23178915355&amp;gbraid=0AAAABBoNLYwg_Uf8W-54O15mVdpq1PfDK&amp;gclid=CjwKCAiAzZ_NBhAEEiwAMtqKy3fFbxRxKVCCXSB6WzTZR9JemlY7GEc8cxf499Iqxe20N4Plr28L-xoCA38QAvD_BwE" rel="nofollow noopener" target="_blank">remains</a> called Grammarly. “When technology works everywhere, it starts to feel ordinary,” Mehrotra wrote in his <a data-offer-url="https://www.grammarly.com/blog/company/announcing-company-rebrand-to-superhuman/" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.grammarly.com/blog/company/announcing-company-rebrand-to-superhuman/&quot;}" href="https://www.grammarly.com/blog/company/announcing-company-rebrand-to-superhuman/" rel="nofollow noopener" target="_blank">press release</a>. “And that usually means something extraordinary is happening under the hood.”</p><p class="paywall">The expanded Grammarly platform now offers an AI solution for every imaginable need—and some you’ve probably never had. There’s an AI chatbot that will answer specific questions as you compose a draft, a “paraphraser” feature that suggests changes in style, a “humanizer” that revises according to a selected voice, an AI grader that predicts how your document would score as college coursework, and even tools for flagging and tweaking phrases commonly produced by large language models. (Sure, you’re using AI to do everything here, but you don’t want it to <em>sound</em> like that.)</p><p class="paywall">Perhaps most insidiously, however, Grammarly now has an “expert review” option that, instead of producing what looks like a generic critique from a nameless LLM, lists a number of real academics and authors available to weigh in on your text. To be clear: Those people have nothing to do with this process. As a disclaimer clarifies: “References to experts in this product are for informational purposes only and do not indicate any affiliation with Grammarly or endorsement by those individuals or entities.”</p><p class="paywall">As advertised on a <a data-offer-url="https://support.grammarly.com/hc/en-us/articles/38552366848781-Grammarly-Expert-Review-user-guide#:~:text=Click%20on%20an%20expert's%20name,icon%20next%20to%20their%20name." class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://support.grammarly.com/hc/en-us/articles/38552366848781-Grammarly-Expert-Review-user-guide#:~:text=Click%20on%20an%20expert's%20name,icon%20next%20to%20their%20name.&quot;}" href="https://support.grammarly.com/hc/en-us/articles/38552366848781-Grammarly-Expert-Review-user-guide#:~:text=Click%20on%20an%20expert's%20name,icon%20next%20to%20their%20name." rel="nofollow noopener" target="_blank">support page</a>, Grammarly users can solicit tips from virtual versions of living writers and scholars such as Stephen King and Neil deGrasse Tyson (neither of whom responded to a request for comment) as well as the deceased, like the editor William Zinsser and astronomer Carl Sagan. Presumably, these different AI agents are trained on the oeuvres of the people they are meant to imitate, though the legality of this content-harvesting remains murky at best, and the subject of many, <em>many</em> <a href="https://www.wired.com/story/ai-copyright-case-tracker/">copyright lawsuits</a>.</p><div><div class="ConsumerMarketingUnitThemedWrapper-kjbXjp gnOkbl consumer-marketing-unit consumer-marketing-unit--article-mid-content" role="presentation" aria-hidden="true"></div><p class="paywall">“Our Expert Review agent examines the writing a user is working on, whether it's a marketing brief or a student project on biodiversity, and leverages our underlying LLM to surface expert content that can help the document's author shape their work,” says Jen Dakin, senior communications manager at Superhuman. “The suggested experts depend on the substance of the writing being evaluated. The Expert Review agent doesn’t claim endorsement or direct participation from those experts; it provides suggestions inspired by works of experts and points users toward influential voices whose scholarship they can then explore more deeply.”</p><p class="paywall">Someone like King may see the advance of AI as <a href="https://www.latimes.com/business/technology/story/2023-08-31/column-stephen-king-i-love-you-but-youre-wrong-about-the-luddites-and-technological-progress">unstoppable</a>, and there may be nobody left to defend Zinsser’s 1976 handbook <em>On Writing Well</em> from the big tech vultures, but what of the countless other luminaries who still want to keep their material from being compressed into an algorithm? Vanessa Heggie, an associate professor of the history of science and medicine at the University of Birmingham, recently took to LinkedIn to share an especially grim example of how the feature works, accusing Superhuman of “creating little LLMs” based on the “scraped work” of the living and dead alike, trading on “their names and reputations.” The screenshot she <a data-offer-url="https://www.linkedin.com/feed/update/urn:li:activity:7434290499089309696/" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.linkedin.com/feed/update/urn:li:activity:7434290499089309696/&quot;}" href="https://www.linkedin.com/feed/update/urn:li:activity:7434290499089309696/" rel="nofollow noopener" target="_blank">posted</a> showed the availability of analysis from an AI agent modeled on David Abulafia, an English historian of the medieval and Renaissance periods who <a data-offer-url="https://www.thetimes.com/uk/obituaries/article/david-abulafia-obituary-author-of-epic-maritime-histories-3gm96jf6v?gaa_at=eafs&amp;gaa_n=AWEtsqfUAqmOq8eOfCIThgqRbl74oCuwoR2LnxsCte_e82rmFPNuArTiu_BPrGZAdW4%3D&amp;gaa_ts=69a76c2a&amp;gaa_sig=EX-l_0HuNAvjykZCgUMnsOYP_DeP4zVemo00xZ4Um7UPv1QrT7WBO_5X9OmXFeoFQelLfG_v5WRT0GJbN7xoCw%3D%3D" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.thetimes.com/uk/obituaries/article/david-abulafia-obituary-author-of-epic-maritime-histories-3gm96jf6v?gaa_at=eafs&amp;gaa_n=AWEtsqfUAqmOq8eOfCIThgqRbl74oCuwoR2LnxsCte_e82rmFPNuArTiu_BPrGZAdW4%3D&amp;gaa_ts=69a76c2a&amp;gaa_sig=EX-l_0HuNAvjykZCgUMnsOYP_DeP4zVemo00xZ4Um7UPv1QrT7WBO_5X9OmXFeoFQelLfG_v5WRT0GJbN7xoCw%3D%3D&quot;}" href="https://www.thetimes.com/uk/obituaries/article/david-abulafia-obituary-author-of-epic-maritime-histories-3gm96jf6v?gaa_at=eafs&amp;gaa_n=AWEtsqfUAqmOq8eOfCIThgqRbl74oCuwoR2LnxsCte_e82rmFPNuArTiu_BPrGZAdW4%3D&amp;gaa_ts=69a76c2a&amp;gaa_sig=EX-l_0HuNAvjykZCgUMnsOYP_DeP4zVemo00xZ4Um7UPv1QrT7WBO_5X9OmXFeoFQelLfG_v5WRT0GJbN7xoCw%3D%3D" rel="nofollow noopener" target="_blank">died in January</a>. “Obscene,” Heggie wrote.</p></div></div></div></div><div class="GridWrapper-uulHE dCnZHU grid grid-margins grid-items-2 ArticlePageChunksGrid-kSknMg dSvDdx grid-layout--adrail narrow wide-adrail" data-journey-hook="grid-wrapper"><div class="GridItem-bufwYC kKTABR grid--item grid-layout__content"><div class="BodyWrapper-cuqCAc eujiPN body body__container article__body" data-journey-hook="client-content" data-testid="BodyWrapper"><div class="body__inner-container"><p class="paywall">An independent review of the Expert Review tool by WIRED reproduced the recommendations for feedback from the Abulafia bot, as well as from models based on the living cognitive scientists Steven Pinker and Gary Marcus. (Neither returned a request for comment.) As the software processed the sample text, it noted that it was taking “inspiration” from <em>Elements of Style</em> author William Strunk Jr. and the sociologist Pierre Bourdieu while applying “ideas” from <em>Gone With the Wind</em> author Margaret Mitchell and using “concepts” from writer and professor Virginia Tufte—all of whom are dead, with Tufte dying most recently, in March 2020. The guidance from her AI agent read: “Replace repetition with vivid, varied sentence patterns.”</p><p class="paywall">C.E. Aubin, a historian and postdoctoral fellow at Yale University who shared Heggie’s LinkedIn post on Bluesky, tells WIRED that Grammarly’s “expert” system “seems to validate the profound mistrust so many scholars in the humanities have for AI and its seemingly constant use in fundamentally unethical ways.”</p><p class="paywall">“These are not expert reviews, because there are no ‘experts’ involved in producing them,” Aubin says. “And it's pretty insulting to see scholarship used this way when the academic humanities are currently under attack from every possible angle—as though the actual people who do the thinking and produce the scholarship are reducible to their work itself and can be removed entirely from the equation.” She says this elimination of personhood is “awful” enough on its own, apart from “the issue of ‘reanimating’ the dead so cynically.”</p><p class="paywall">Beyond the dubious ethics, there’s the question of whether these proliferating AI widgets are even effective or helpful. Grammarly’s plagiarism detector, for instance, didn’t catch a direct quotation I used from a scene in <em>The Simpsons</em> where Bart improvises a geography presentation he hasn’t prepared for, leading to an empty summation: “In conclusion, Libya is a land of contrasts.” (Grammarly did warn, however, that “a land of contrasts” is a sequence of words often generated by LLMs.)</p><p class="paywall">Over the past several years, teachers and professors have struggled through a deluge of <a href="https://www.wired.com/story/student-papers-generative-ai-turnitin/">AI-written essays</a>, finding it difficult to wean their pupils off of this <a href="https://www.media.mit.edu/publications/your-brain-on-chatgpt/">self-defeating shortcut</a>. And even before Grammarly had its “experts,” those who relied on it to proofread their papers were occasionally <a data-offer-url="https://thehill.com/changing-america/enrichment/education/4506271-student-fights-ai-cheating-allegations-for-using-grammarly/" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://thehill.com/changing-america/enrichment/education/4506271-student-fights-ai-cheating-allegations-for-using-grammarly/&quot;}" href="https://thehill.com/changing-america/enrichment/education/4506271-student-fights-ai-cheating-allegations-for-using-grammarly/" rel="nofollow noopener" target="_blank">accused of cheating</a> after the material was flagged by AI detection services. Giving these users the impression that they can have their work evaluated by leading thinkers before they turn it in may contribute to their sense that they are only double-checking their text, not violating any academic code of conduct.</p><p class="paywall">But at least students can enjoy having their homework assessed by illusory mentors instead of their actual instructors, which may or may not be a slippery slope toward <a data-offer-url="https://www.forbes.com/sites/benjaminwolff/2026/01/23/at-davos-alex-karp-was-right-and-wrong-about-the-future-of-jobs/" class="external-link" data-event-click="{&quot;element&quot;:&quot;ExternalLink&quot;,&quot;outgoingURL&quot;:&quot;https://www.forbes.com/sites/benjaminwolff/2026/01/23/at-davos-alex-karp-was-right-and-wrong-about-the-future-of-jobs/&quot;}" href="https://www.forbes.com/sites/benjaminwolff/2026/01/23/at-davos-alex-karp-was-right-and-wrong-about-the-future-of-jobs/" rel="nofollow noopener" target="_blank">eliminating school faculty altogether</a>. Shouldn’t take long to find out!</p></div></div></div></div></div><div class="GridWrapper-uulHE dCnZHU grid grid-margins grid-items-2 PaywallInlineBarrierWithWrapperGrid-gsjZKQ bxuhND grid-layout--adrail narrow wide-adrail" data-journey-hook="grid-wrapper"><div class="GridItem-bufwYC kKTABR grid--item grid-layout__content"><div class="body body__inline-barrier article__body"><div class="container container--body"><div class="container--body-inner"></div></div></div></div></div><div class="GridWrapper-uulHE dCnZHU grid grid-margins grid-items-2 ContentWrapperGrid-hbJRnx cYtuEk grid-layout--adrail narrow wide-adrail" data-journey-hook="grid-wrapper"><div class="GridItem-bufwYC kKTABR grid--item grid-layout__content"><div class="body body__container"><div class="container container--body"></div></div></div></div></div></div></div></div></div>]]></description>
      <link>https://www.wired.com/story/grammarly-is-offering-expert-ai-reviews-from-your-favorite-authors-dead-or-alive/</link>
      <guid>https://www.wired.com/story/grammarly-is-offering-expert-ai-reviews-from-your-favorite-authors-dead-or-alive/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[You don’t have to if you don’t want to. § Scott Smitelli]]></title>
      <description><![CDATA[<p>I’m sure you’re wondering why I called you all here today. Well, to be honest, I didn’t actually call for <em>all</em> of you; some of you probably shouldn’t be here. You folks might want to quietly find your way to the exits right here and right now.</p><p>For those readers who are sticking around, I suspect I’m going to lose a fair number of you along the way. We’re going to attempt to thread a pretty tough needle here and I won’t be too terribly offended if some browser tabs get closed before we get there.</p><p>And hell, may as well say it: The opinions expressed here belong solely to me and do not reflect the views of my employer, and they probably don’t reflect the views of anyone else’s employer either.</p><p>This is for the people who look at the world and feel like everything and everybody has gone crazy. People who maybe have this nagging feeling deep inside that something isn’t right here, but may be unsure about speaking up for fear of being ostracized at work or in social circles. Those of us who pause, look at this barrage of everything happening around us every day, and simply want to say no.</p><p>If anyone out there has thought for the very first time that this might finally be the new trick that makes them feel like an old dog, or if you’re a fresh graduate who spent years working through school toward an almost-certain career path that seems now to be crumbling into dust underfoot, you are the intended audience.</p><p>I’m writing this to tell you that it’s not just you. But more importantly, you’re not wrong. You are free to feel what you feel and think what you think. And I, for one, am tired of listening to people who tell me to suppress those parts of myself and surrender to a new way of being that I never asked for and frankly do not want.</p><p>Pull up a chair and endure yet another goddamn article about generative AI.</p><h2 id="gotta-blame-it-on-something">Gotta blame it on something</h2><p>In 1989, a musical act called Milli Vanilli had a number one hit titled “<a href="https://www.youtube.com/watch?v=vQhcLCd2MCg" rel="external" data-link-id="youtube-baby-dont-forget-my-number">Baby Don’t Forget My Number</a>.” Its success, alongside the earlier single “<a href="https://www.youtube.com/watch?v=IJk66tLOTL4" rel="external" data-link-id="youtube-girl-you-know-its-true">Girl You Know It’s True</a>,” secured them a spot on the <em>Club MTV Tour</em>. During one of the performances, a technical glitch caused their pre-recorded vocal track to skip and repeat, clearly betraying the fact that they had been lip-syncing to the voices of other singers. It didn’t take long before news broke that the performers on the stage that night had never sung <em>any</em> of their music—live or album versions.</p><p>In the fallout from this incident, their record label severed ties with them, their Grammy award was rescinded, and their albums were pulled from shelves. The performers, Fab Morvan and Rob Pilatus, never found any lasting success after the dissolution of the group. Lawsuits were filed by groups of customers who felt that they were sold fraudulent goods using deceptive practices. To this day, the name Milli Vanilli remains tainted by the scandal.</p><p>Maybe it’s just me, but I feel that same kind of treachery when somebody tries to pass off a piece of AI-generated work as if it were their own voice. There’s always that moment—whether reading the text, examining the image, or listening to the spoken language—where I clock the presentation as “not quite right.” Then the realization hits that I’ve been engaging with nothing of any particular substance, then I become a little pissed off at having my time and attention wasted by somebody who didn’t care enough about what they were doing to actually do that thing.</p><p>Recently that feeling of indignation has started becoming displaced by something a bit more melancholy. AI restaurant reviews praising a dish that definitely is not offered on the menu, and the attentive service provided by a named member of the staff who doesn’t exist. Video recommendations featuring an algorithmic guess at the swimming motions of a newborn sea otter or the simulated smile of a down-on-his-luck war vet reuniting with a service dog. Has anybody with a mouth ever tasted this cookie recipe? Has anybody with an actual butt contributed any of the five-star reviews listed next to this dining chair?</p><p>We’ve got enough content to infinite-scroll for the rest of our waking lives. Yet so much of it is pointless, undesirable, lacking substance, or actively harmful. It is above all <em>joyless</em>—like listening to a Breaking Rust album <mark class="mn-sn-content margin">There has been plenty of commentary regarding the <a href="https://www.boston.com/culture/entertainment/2025/11/30/ai-country-hit-walk-my-walk-built-on-blanco-browns-sound-sparks-questions-of-attribution-ethics/" rel="external" data-link-id="boston-walk-my-walk-blanco-brown">apparently 100% AI-produced track “Walk My Walk,”</a> but there is some real gold in the Singles and EPs category on (one of) Breaking Rust’s artist pages on Spotify. In particular, a <a href="https://open.spotify.com/track/7M3ZNzRA5xCn0yO4r5ntjh" rel="external" data-link-id="spotify-breaking-rust-photograph">relatively recent cover of “Photograph”</a> that answers the question “What if we got Ben E. King’s backing band, put a Temu clone of Chris Stapleton’s voice on top of it, and did an Ed Sheeran song that went for <em>eight and a half minutes?</em>” It is not pleasant and it does not need to exist.</mark></p><p><mark class="mn-sn-content margin">If that’s not to your taste, there’s also an <a href="https://open.spotify.com/track/7Cp309HTD2Rw2eGEcKuovL" rel="external" data-link-id="spotify-breaking-rust-let-her-go">eleven minute version of Passenger’s “Let Her Go”</a> up there. (Everything okay with your end of sequence tokens, buddy? Just concerned is all.)</mark> while eating a sleeve of unsalted saltines and somehow forgetting that it wasn’t always this way.</p><p>Look at LinkedIn for chrissakes. “A senior engineer was tasked with such-and-such,” “The consultant billed for sixty hours,” “Our backlog had grown to over a thousand tickets,” “When I saw the 350,000 line pull request the junior engineer had opened,” and on and on. These are not real things that have happened to living people. They are the result of somebody prompting a chat bot to “make me sound smart and insightful to a room full of people who have long since turned their brains off” while conveying nothing novel or actionable. I have recently started referring to these “thought” “leadership” social media posts collectively as <strong>AIslop’s Fables</strong>.</p><p>If you’ll indulge me, I’d like to take a brief tangent and try my hand at writing one of these ridiculous things myself:</p><blockquote>
<p>Two engineers—the systems architect Ass and the solution consultant Weasel—chanced to travel in company down a forest aisle. The Ass walked purposefully several paces ahead of the Weasel, who dawdled merrily along. At last they paused at a fork in the codebase.</p>
<p>The Ass, ever considerate of the broader consequences of his actions, contemplated deeply the choice before him. The Weasel, uninterested in such unrewarding efforts, took rest at the base of a widespreading trie, finding great pleasure in the cool shade of its stable branches.</p>
<p>So offended was the Ass at this display of poor work ethic, he deigned to question the Weasel’s technical ability. “How foolish you should be,” he brayed, “to remain unbothered by the fact that your house contains one appliance called a washing machine and another called a dishwasher. Until you see the absurdity of it, you have no business designing an API!”</p>
<p>It was in that moment, and all at once, when Jupiter cast down a fierce reallocation of resources that made both of their roles redundant.</p>
<footer>The AIslopica 001. The Ass and the Weasel</footer></blockquote><p>Anyway. I find that when I mentally filter out all the obvious AI flourishes—the empty fluff, the <a href="https://www.scottsmitelli.com/articles/em-dash-tool/">excessive emoji</a>, the formatting smells, the Ghibli-inspired scenes that really, <em>really</em> love using every available shade of brown—there’s sometimes not a whole lot of genuine human connection left in there. And in that empty space, I begin to wonder: Where did all the people go? What are they all doing behind the artifice they’re showing here? Why am I wasting my time and energy wading through these shallow yet unbounded seas of <em>nothing?</em></p><p>For a while I was able to navigate around it by really curtailing my use of social media. I only looked at LinkedIn for the S-tier trolling of a select group of professional shitposters. Reddit no longer occupied any appreciable amount of my time. There were entire classes of Hacker News submissions that I refused to read the comments on.<mark class="mn-sn-content side">Including the comments about this article, should such comments ever materialize.</mark> I experimented with a small set of browser customizations to eliminate YouTube video recommendations and the site’s ill-conceived Shorts.</p><p>In place of all that, I started spending much more time in smaller private communities of people with shared interests, personalities, or life experience. We’d swap links to things we thought might be interesting to the group. We wouldn’t chase trends, we didn’t let ourselves get overloaded with shiny distractions from outside the circle, and we evolved it into a shared space that suited all of us best. Spending time in these small isolated groups really laid bare how <em>dogshit</em> the social landscape on the broader internet felt in comparison.</p><p>I was all set to leave that part of my life behind me. Then it followed me to work.</p><h2 id="if-a-clod-be-washed-away-by-the-c">If a clod be washed away by the C</h2><p>There are lots of different jobs out there, and a fair number of them are done on computers. As a matter of fact, when people ask me what I do for a living, I sometimes simply wave my hand and say “Computers” in a kind of no-you-really-don’t-want-to-know-what-Kubernetes-is kind of way. I suspect most office workers have a similar aspect of their job that they don’t like to dredge up during polite conversation.</p><p>I’m a software engineer on paper, and that’s the framing I’ll use here because it’s the one I know best. But I’m sure that those working in design, marketing, visual art, customer service, writing, all sorts of disciplines have felt it too. This ever-louder voice booming from on high to integrate <strong>large language models</strong> (LLMs) and other generative AI products into every conceivable point in your workstream. Maybe against your will. Probably against your own interests.</p><p>In the software engineering world, at least until quite recently, we all wrote computer code. Some of us wore the title “<strong>coder</strong>” like a badge of honor to describe our profession.<mark class="mn-sn-content side">I never much cared for it.</mark> We spent basically the entire 2010s loudly promoting “Learn to code!” as the cure for all of the ails of that era. And coders entered the profession in droves. With a <em>teeny-tiny</em> bit of help from years and years of interest rates near zero, the industry flourished.</p><p>There are a bunch of different types of computer code, and one way to visualize the different categories is to imagine them as the decks on a ship. At the bottom, in the sweltering boiler room, we have the <strong>machine code</strong>—the ones and zeros that computers are real good at but humans are real bad at. Above that we have an <strong>assembly language</strong> layer, still cryptic as all hell but at least comprehensible to a skilled and attentive person who subsists entirely on coffee. Above that we have <strong>systems languages</strong> like C and Rust <mark class="mn-sn-content margin">And maybe Go if you wanna get into fights with certain people.</mark> which strike a pretty good balance between raw control over the computer and ease of getting things done.</p><p>One deck higher, we find ourselves among the <strong>interpreted languages</strong> like Python and JavaScript which hide a whole bunch of underlying concepts away in the name of making the code easier to write and reason about. And yet above that, a whole ecosystem of <strong>low-code</strong> products which boast point-and-click interfaces for building entire applications on top of hosted platforms. These would be things like Framer and Squarespace. Heck, let’s throw Excel and Power BI into that pile as well.</p><p>In this hierarchy, the upper level languages mechanically generate the code at the layer(s) beneath. If you are working in assembly code, a tool called an <strong>assembler</strong> translates it into machine code without you needing to think about it very much. If you write C or Rust, a <strong>compiler</strong> takes care of the assembly aspects of the program. Python and JavaScript are executed by <strong>interpreters</strong>, which were each written in compiled languages, and so forth. Whichever layer you work in, your code ultimately needs to be translated all the way down to machine code for a computer to make any direct use of it.</p><p>What we’ve got now is perhaps the uppermost deck of the ship: <strong>prompt driven development</strong>. The apparent goal here is to eventually remove all direct manipulation of all types of code, obviating even the pointing and clicking to move different pieces of the app around to suit one’s visual preferences. No, in this paradigm you type out exactly what you want in plain English,<mark class="mn-sn-content side">You can certainly try to prompt in any of the world’s languages, but <a href="https://news.stanford.edu/stories/2025/05/digital-divide-ai-llms-exclusion-non-english-speakers-research" rel="external" data-link-id="stanford-llms-non-english-speakers">results are not guaranteed</a>.</mark> and an LLM chews on that prompt for a little while then writes the necessary code in one of the lower-level languages on your behalf. Don’t like what comes out? Prompt it again, and the code will change to something else. Precisely how does it change? Don’t concern yourself with such trivial matters. Just like when you change a line of Python code, you really don’t need to see what happens at the assembly level either.</p><p>There is a key difference here: When you change that line of Python code, you <em>can</em> know what is affected. Every step in the program’s execution adheres to a rigid set of rules that is followed precisely, each and every time. You <em>can</em> know that extending a string past a certain length triggers a memory allocation, and in this one degenerate case it causes a register spill leading to a performance hitch that can be reliably replicated, tested for, and worked around. It’s deeply tedious to trudge through the lower decks of the ship this way, but it is feasible.</p><p>How does an LLM produce its output? <a href="https://www.technologyreview.com/2024/03/04/1089403/large-language-models-amazing-but-nobody-knows-why/" rel="external" data-link-id="technologyreview-large-language-models-amazing-but-nobody-knows-why">Nobody knows.</a> I mean, we <em>know</em> in the abstract sense, but not to the extent where we can attribute a certain behavior to a given machine state. It’s simply not possible to trace everything that occurred across the hundreds of billions of parameters that underpin each model and replay even a fraction of the steps that transformed a given piece of context into a specific output token. It’s easy to think of this an inherent form of <strong>nondeterminism</strong>, where the output of a system varies based on factors beyond what was provided as input,<mark class="mn-sn-content side">Compare this with the quote “Insanity is repeating the same mistakes and expecting different results” (which evidently originated in a <a href="https://quoteinvestigator.com/2017/03/23/same/" rel="external" data-link-id="quoteinvestigator-insanity">twelve-step pamphlet</a>).</mark> but it’s more attributable to an intentional setting called <strong>temperature</strong>—a controlled introduction of randomness that reduces the likelihood that the model parrots back such a large fragment of training data that it gets itself stuck or veers into plagiarism territory. Turns out this property has a tendency to break existing code during attempts to make unrelated changes. To defend against that, the industry has turned to <strong>coding agents</strong> that incrementally make these changes in a loop, ideally finding a stable equilibrium where the new thing works and none of the existing things break. This is pretty much where we are now, with some engineers experimenting with running multiple agents concurrently<mark class="mn-sn-content side">Maybe using something like Clawdbot. I mean Moltbot. I mean OpenClaw.</mark> to observe and correct each other’s work.</p><p>But you didn’t come here for a slapdash and oversimplified explanation of eighty years of programming history. You’re here for boat metaphors!</p><p>Long time ago, probably before either you or I got into this game, the old RMS <em>Software Engineering</em> struck an iceberg that tore a big gaping hole down the side of her hull. The Machine Code deck flooded first, and like literal rats escaping a literal sinking ship, the machine programmers sought higher ground on the Assembly Language deck. Water began flooding the assembly programmers out, and aside from a few air pockets where the embedded systems programmers sought refuge, everyone hurried up to C deck.</p><p>By this point, news had spread that “up near the top” was where everybody wanted to be—although the reasons <em>why</em> got a little lost in the hustle—so a huge number of programmers arrived at the Interpreted Language decks. <mark class="mn-sn-content margin">This was pretty much where I came in.</mark> Some hung around for a good fifteen or twenty years, but the rising water waits for nobody. Higher still we climbed, skipping right past the Low-Code mezzanine and straight up to the Prompting promenade on the main deck. It is here that we’ve reached our apex; there’s nothing above us but the twinkling stars punctuating the pitch black sky. From here, all the decks below do our bidding. With just a flick of the wrist, huge quantities of lower-level code are willed into existence without intervention. Simply marvelous.</p><p>Except… the ship is still taking on water. Sooner or later every deck—including the one the prompters are now standing on—will go under. If you subscribe to the idea that technology will invariably improve and build on top of everything that has come before it, often to the point of completely encapsulating it, why is “writing all that prompt text” such a bright red line of magical job security? Text was the <em>first thing</em> language models ever produced! You really can’t envision a future where people think it’s quaint and old-timey to write LLM prompts by hand?</p><p>And what happens to us in that metaphor? Just chillin’, clinging to flotsam, slowly freezing to death in the North Atlantic.</p><h2 id="yolodr">yolo;dr</h2><p>Let me be crystal clear: Not everybody wants to write software in paragraph form.</p><p>In fact, I might propose the possibility that the techniques emerging today are a totally distinct discipline from traditional software engineering. Perhaps the two might coexist peacefully if we could simply agree to stay the hell out of each other’s lanes.</p><p>But let’s be real, that’s not how this seems to be going.</p><p>At multiple points in my life, I’ve had the opportunity to debate my peers over the following question: Is software engineering an art, or a science? The science argument is bolstered by the fact that a disheartening proportion of people who work in this industry seem utterly incapable of appreciating art in any capacity, <mark class="mn-sn-content margin">An interesting counterexample: Software engineers are often fans of anime, a form of art. (As an exercise, try to get an engineer to articulate exactly what they appreciate about it.)</mark> let alone creating any. On the other side, they’ve had the affirmation “code is poetry”<mark class="mn-sn-content side">And to date, the only form of poetry for which MITRE has assigned multiple CVEs.</mark> emblazoned on the footer of the <a href="https://wordpress.org/" rel="external" data-link-id="wordpress">WordPress.org site</a> for nearly a quarter century. I’ve long believed—and still believe—that there is a spectrum and things can be both. Look at a cable-stayed bridge, or a <a href="https://www.timhunkin.com/" rel="external" data-link-id="tim-hunkin">Tim Hunkin</a> sculpture, or some of the stupid shit the contestants on <em>The Great British Baking Show</em> have been asked to make over the past couple of seasons, and tell me that these didn’t require the unique touch of an artist <em>and</em> an engineer. In the right light, software is no different.</p><p>Engineers work in specifications and requirements. The end product needs to behave a certain way, adhere to certain external constraints, meet relevant regulatory criteria, not kill anybody,<mark class="mn-sn-content side">Unless the requirements say it should.</mark> that type of thing. Artists work in the ambiguous undefined spaces that permeate all the little in-between areas of the work. Somebody has to make the countless tiny decisions that aren’t otherwise spelled out in black and white on the ticket. The sum total of all these little decisions becomes something that looks and feels a lot like style, even taste. The choices being made here are influenced by a working lifetime of personal experiences. Perhaps one could go as far as suggesting that it involves a certain intuition to do it well. We’re really okay with outsourcing this aspect of our work to some tensor core randomly burping out floating point rounding errors?</p><p>There are countless ways to express the same idea. Are some expressions of a particular idea better than others? Arguably!</p><p>“But wait,” I hear you cry. “Once the product ships, nobody sees the code anyway! Who cares how it looks?” Take a long, hard look around you. Look at your phone. Look at one of the dozens of other web pages you have open. Look at the app launcher on your smart TV. Look at the <a href="https://www.scottsmitelli.com/articles/et-tu-panera/">ordering kiosks at Panera</a>. Look at every furtive data broker who mishandled your personal information and offered a $125 credit monitoring voucher<mark class="mn-sn-content side">You never bothered to redeem that, did you?</mark> as restitution for their negligence. Look at every hateful airline website or clunky automotive touchscreen or inkjet printer driver and tell me with a straight face that code quality doesn’t matter—that whatever makes these products so <em>miserable</em> to interact with day in and day out could not <em>in any way</em> be improved by exercising more care in the expression of the underlying code.</p><p>Look around you. You don’t believe that this could be true?</p><p>When I hear people say “I ship code that I don’t read,” what I hear in my head is “I really do not care about what the end-user of this product experiences, I do not care about whichever poor soul needs to maintain this thing after I’ve gotten bored with paying attention to it, I do not care about anybody on my team who has to support the ongoing operation of it, and frankly I didn’t even care about making it in the first place. I just wanted to be done for the sake of being done.” It is a vulgar display of apathy, a shameful dereliction of sound engineering practices, and quite frankly it makes the practitioner sound like an insufferable asshat. To wield something so limitlessly powerful as software without so much as the slightest reverence for the craft is simply offensive. Truly. I am viscerally disgusted by what I am watching transpire in this space.</p><p>“Aha! I’ve got you now,” you bellow, in a different style of voice for some reason. “This is gatekeeping! You are trying to protect your little clubhouse from outsiders who hold viewpoints that differ from yours!” Guilty as charged; I am indeed gatekeeping. I’m gatekeeping in the same way all those pesky government officials gatekeep when they tell us we’re not allowed to work toward achieving nuclear fission in the shed. Turns out we live in a society, and the actions of one person have the capacity to directly and indirectly affect countless others. If there’s an activity that has a high likelihood of causing preventable injury or tying up first responders unnecessarily, those activities tend to get restricted in some way.</p><p>Software runs the world. It can make (or lose) untold sums of money. It can decide who gets a favorable mortgage rate or a critical job interview. It can know our deepest secrets, and it can surveil us against our will. It can bombard us with advertisements targeted at personality traits we’re not even aware we’re revealing. It can cause accidental (or deliberate) death. More commonly, it can really frustrate, annoy, inconvenience, and subtly chip away at the mental well-being of vast swaths of the inhabitants of this planet we all share. Stop treating it like it’s anything less.</p><h2 id="i-owe-my-soul-to-the-company-store">I owe my soul to the company store</h2><p>Not everybody is okay with the idea of becoming dependent on an outside party in order to do their work.</p><p><em>Tools.</em> That’s the word that everybody likes to volley around. AI models are tools, the same kind of thing as what I get from Home Depot when I rent a wallpaper steamer. Same as what companies get when they pay Adobe for a Photoshop subscription. Gotta spend money to make money, as the saying goes. “LLM coding agents are tools—nothing more—so just pay for a license seat and use it like you would any other tool.”</p><p>You ever get the feeling that something is different about the AI case, but you can’t quite put your finger on it? You ever say a word like ‘couch’ out loud too many times, and the sound momentarily loses its meaning? <mark class="mn-sn-content margin">There’s a term for the phenomenon, by the way: <a href="https://en.wikipedia.org/wiki/Semantic_satiation" rel="external" data-link-id="wiki-semantic-satiation">semantic satiation</a>.</mark> Did we all collectively forget precisely what a tool even is?</p><p>Suppose there’s a slotted-head screw somewhere in your environment that you wish to tighten. You could extend the index finger on your dominant hand, insert the free edge of your nail plate into the slot, and turn your wrist. Depending on the state of the screw, this will probably cause some amount of injury to your fingernail. The mental image certainly made me cringe a little.</p><p>A far more effective technique would be to find a slotted screwdriver, grasp it in your hand, and perform substantially the same motion to accomplish the task. Brains have the rather remarkable ability to treat handheld objects as an extension of the body without a whole lot of cognitive overhead. Both a fingernail and a screwdriver permit a being of agency and free will to impart some change to their environment. Both the fingernail and the screwdriver are pretty unambiguously tools.</p><p>The elegant simplicity of the screwdriver makes it useful for more than just driving screws. One could—in a pinch—use a screwdriver to pry two pieces apart, or one could use it to shave a piece of wood or other malleable material down, or one could bring it down to the mess hall to finally shank Jimmy the Rat. Whatever a person might want to do with a hand-held object having a screwdriver’s material properties, they are free to do it.</p><p>Somewhere in another part of town, on the fourth floor of a three-star chain hotel, an ice machine hums dutifully in the elevator lobby. This is a self-contained appliance that draws utility power and water from the building and converts it into ice cubes.<mark class="mn-sn-content side">Along with noise and waste heat.</mark> That’s all it does, all day every day, whether anyone is paying attention to it or not. Is the ice machine a tool like the screwdriver is? Does the answer to that question change in any way if nobody ever passes by and presses its button?</p><p>Conceptually between these two objects, we have the power screwdriver. This is a handheld device that converts electrical power into torque<mark class="mn-sn-content side">Along with noise and waste heat.</mark> that turns a slotted bit. The operator manipulates this in a way that’s not too different from the regular screwdriver, moving it around and positioning the bit in the screw head, but instead of doing the difficult work of repeatedly twisting their wrist to move the screw, all they need to do is press a button to release stored energy and channel it into the act of turning. <mark class="mn-sn-content margin">The operator also needs to know when to <em>release</em> the button, a lesson that comes from stripped threads, cammed-out heads, and splintered wood.</mark> This is a far more efficient way to drive screws. It allows more screws to be driven over a given span of time, and it conserves the operator’s energy and really saves their wrist from long-term injury.</p><p>Yet in removing the most laborious and time-consuming part of turning screws, the power screwdriver has lost some of the generality that the regular screwdriver enjoys. Its awkward form factor and stubby bit–chuck arrangement prevents it from being useful at prying or chiseling, and it’s definitely not the best way to deal with our pesky cellmate.</p><p>In fact, the narrow specialization of the power screwdriver is part of the reason why regular screwdrivers still exist. I would guess that almost every person with a power screwdriver in their garage also has <em>multiple</em> regular screwdrivers as well. They each have their time and their place. I would not use a power screwdriver to change a watch battery, and I would not use a regular screwdriver to mount a 65-inch TV to a pair of wall studs. Both of these items are in my toolbox; I see no difficulty calling both of them tools.</p><p>So, what is generative AI? Is it a power screwdriver that removes sporadic moments of fleeting agony from a much larger home improvement project? Is it an ice machine loudly grinding unrequested ice cubes onto the tile floor at two o’clock in the morning? Or is it a stick of dynamite—light the fuse, plug your ears, and run the hell away from whatever happens next?</p><p>It can be all of these things, it seems. I guess AI really does satisfy the definition of a tool as long as it’s being used as one.</p><p>This unlocks a common refrain from the booster class: “A true craftsperson uses every tool at their disposal!” Which, if you think about it for more than three seconds, is ridiculous on its face. Gotta dig some holes for fence posts? Okay! Bring along every shovel on the truck, the Ditch Witch, a box of ANFO and the <a href="https://www.sibo.eu/en/bagger-293/" rel="external" data-link-id="sibo-bagger-293">Bagger 293</a>. Have the people who echo this kind of stuff ever built <em>anything</em> in the physical world? Your average craftsperson has one <em>real good</em> compound miter saw that they use for basically every cut on the jobsite. They’ll use it until it breaks down, then they’ll replace it with a newer model of substantially the same thing. <mark class="mn-sn-content margin">You know why they stick with what they know? <em>Because they know it.</em> They’ve invested a lot of effort learning quirks, shortcuts, and building up muscle memory on it.</mark> In what world is constantly switching tools for the sake of switching tools a remotely smart use of time?</p><p>But there’s a deeper theme I wanted to touch on here. There’s a random piece of advice that’s been floating around my head for years: <em>Don’t rent your livelihood.</em><mark class="mn-sn-content side">I wish I knew where I picked this up from so I could properly attribute the source, but my research so far has turned up nothing.</mark> That is to say, if there is a tool or system on which your entire professional success rests, do everything you can to ensure that it’s not something you need to repeatedly pay other people to acquire. For example, if you own and operate a moving company, it would be wise to not need to rely on a rental company to provide a truck for you to use every day. Such reliance would effectively put you entirely at the rental company’s mercy. If they want to jack up their day rates, that hurts your bottom line. If you show up the morning before a big move and they already rented all their trucks out to other customers, your entire operation stops cold.</p><p>Obviously there is nuance to it. If you’re a landscaping company and you only need the Ditch Witch on certain days, it’s less risky and more fiscally responsible to rent that. If you can’t get it, it’s not like the business completely shuts down. I’m talking about the fundamental everyday stuff here: the plumber’s wrench, the musician’s cello, the photographer’s camera body.</p><p>Paying a subscription fee for AI feels like something between outsourcing the work and renting a brain. Neither one is a particularly great feeling, at least to me. The outsourcing aspect is pretty clear-cut: If you are doing this as an employee, the company hired <em>you</em> and everything you bring to the table—your judgement, your experience, your personality, and so on. If you wouldn’t have commissioned some dude off Fiverr to do your job for you in 2021, what’s suddenly different now? Even if the business paid for the license on your behalf, does it really change the fact that <em>it ain’t really you doing that work anymore?</em> What do they even need you for, anyway?</p><p>The rent-a-brain aspect is more acutely alarming. And I will be blunt here: It sure does seem like the prolonged use of LLMs can reliably <a href="https://futurism.com/openai-investor-chatgpt-mental-health" rel="external" data-link-id="futurism-chatgpt-mental-health">turn certain people’s minds into mush</a>. Perhaps there’s a bit of a correlation–causation aspect, but I do not like the effects I’m seeing out there.</p><p>Stop me if you’ve heard this one before: “After [however long] using AI coding assistants, there’s no way I’m going back!” You know, I don’t doubt that this is true. Because I’m not sure some of the people who say this <em>could</em> go back. It reads like praise on the surface, but those same words betray a chilling sense of dependence. “I gambled away my life savings, I can’t stop now.” “I’m now addicted to heroin, why would I give that up?” “I lost a piece of myself that I can’t even remember ever having, adapt or get left behind! ” Do you actually want to end up in a place where you feel you can no longer escape?</p><p>If you do knowledge work, your brain is your livelihood. Don’t rent your brain from some third party, especially a third party that may not have your best interests at heart. How much do you suppose these LLM tokens actually cost once you factor in the amortized expense of training multiple models over all the content that has ever been exposed to the internet? What do they cost once the VC firm needs to see a return on their investment, or the financing deals come due, or the shareholders get spooked and somebody’s stock price tanks? How much will you need to pay each month to rent your livelihood back from these companies once their offerings aren’t so heavily subsidized and your brain has completely atrophied? <mark class="mn-sn-content margin">You think you’re just gonna self-host an open weight model like GLM-5 on your personal hardware and cut out the hosting costs? Well, alright, hope you have <a href="https://apxml.com/models/glm-5" rel="external" data-link-id="apxml-glm-5">1,727 GB of VRAM</a> lying around.</mark> What will you do when the frontier models start inserting “sponsored thoughts” into the work you tasked them with? Will you respond to a token rate limit message the same way a junkie goes through withdrawal?</p><p>We live in a <em>capitalist</em> society. The line must go up at all costs. For a while this was easy in the technology space because computers kept gaining new capabilities. “Finally, we can do color!” “This one can play CD-ROMs!” “Now this one can run the hottest new game!” “It streams online videos!”<mark class="mn-sn-content side">Barely.</mark> It felt like every couple of years there was a truly compelling reason to re-buy your computer. You ever notice how that kinda petered out at least a decade ago? Computers today feel pretty much like the computers did in 2016. We stopped seeing worthwhile advances in features that anybody was clamoring for. Virtual reality is a niche platform at best, cryptocurrencies and NFTs didn’t meaningfully change much of anything outside of the grift industry, and the sole motivating factor for me buying my last three smartphones was “the new one isn’t running out of storage space and the battery works.”</p><p>I doubt anybody really wants to face this fact, but technology is in a terrible slump. The industry desperately needs something—anything—to entice that almighty line to go up. If AI can’t do it, there aren’t a whole lot of other things right now to be optimistic about. Web3 didn’t work. The Metaverse turned into a seemingly obscure multi-player game called <em>Horizon Worlds</em>.<mark class="mn-sn-content side">Did you know? I didn’t.</mark> We’ve already built all the unregulated taxi companies<mark class="mn-sn-content side">Lyft, Uber</mark> and illegal hotel conversions.<mark class="mn-sn-content side">Airbnb, Vrbo</mark> None of humanity’s actual problems appear sexy (or tractable) enough for the tech industry to concern itself with. So this is what we’ve got. AI is the one basket into which we have feverishly dumped hundreds of billions of dollars worth of our eggs.</p><p>And best of luck to us with all that.</p><h2 id="nothing-for-money">Nothing for money</h2><p>A single DGX B200 AI server is rated to consume <a href="https://www.nvidia.com/en-us/data-center/dgx-b200/" rel="external" data-link-id="nvidia-dgx-b200">14,300 watts</a> of electrical power at peak. You can cram about <a href="https://docs.nvidia.com/https:/docs.nvidia.com/nvidia-dgx-superpod-data-center-best-practices-with-dgx-b200.pdf" rel="external" data-link-id="nvidia-dgx-superpod-best-practices">four</a> of these on a rack if you like to live on the edge, and these four units might draw something like 200 amps of current combined. For a point of comparison, a typical single-family home in the United States will have wires from the utility company that are thick enough to provide a 200 amp service. <mark class="mn-sn-content margin">And much like a single-family home, each of these servers costs a couple hundred thousand dollars.</mark> Your average datacenter will contain one or two dozen of these racks along each of its aisles, with aisles spaced about every ten feet, filling up a floor area that dwarfs the warehouse at the end of <em>Raiders of the Lost Ark</em>. Such datacenters are sprouting up in cities all across the globe, as fast as their tenants are able to pay for them.<mark class="mn-sn-content side">Just kidding. They’re going up <em>faster</em> than their tenants can pay for them.</mark></p><p>As far as the physical world is concerned, computers don’t really do anything useful. They don’t move around, they don’t produce much light, there are no important chemical reactions occurring inside, and they’re specifically engineered not to emit strong radio waves or electromagnetic fields. The only thing they can really do with the electrical energy they consume is convert it into heat. So they do. Most of the 14.3 kW taken from utility power is converted to heat, with the number-crunching stuff as its byproduct. <mark class="mn-sn-content margin">A typical household space heater might be rated at 1.5 kW. A single B200 server dissipates nearly <em>ten times</em> that amount.</mark> These things are <em>belching</em> heat into their surroundings.</p><p>Each server is packed with <a href="https://www.youtube.com/watch?v=7BtNBv9JK6c" rel="external" data-link-id="youtube-dgx-b200-startup">ventilation fans</a> that emit sound pressure levels <a href="https://docs.nvidia.com/https:/docs.nvidia.com/nvidia-dgx-superpod-data-center-best-practices-with-dgx-b200.pdf" rel="external" data-link-id="nvidia-dgx-superpod-best-practices">approaching 100 decibels</a>—approximately as loud as a jackhammer as perceived by its operator. A datacenter aisle packed with AI servers is so deafening that even wearing earplugs underneath earmuffs <a href="https://docs.nvidia.com/dgx-superpod/design-guides/dgx-superpod-data-center-design-h100/latest/sound.html" rel="external" data-link-id="nvidia-dgx-superpod-sound">does not provide enough attenuation</a> to protect against long-term hearing damage. To keep the servers from baking themselves, huge industrial-scale air conditioning systems pump the heat away and dump it into the ambient air outside the building. When citizens raise concerns about datacenters depleting local water supplies, this is where that water is going: The air conditioning systems apply the heat to the water, which causes the water to evaporate into the atmosphere. <mark class="mn-sn-content margin">See, they’re not <em>using</em> water, they’re merely <em>converting</em> it into clouds. Which then causes rain. Which either falls on the ocean so we can’t easily use that water again, or it falls on another part of the country as catastrophic flooding. Totally renewable, don’t worry about it.</mark> The evaporated water carries the heat away, and what’s left on the ground is cooled as a result. The pumps that drive this process consume yet more electricity.</p><p>A six-inch Spicy Italian Sub from Subway contains <a href="https://www.subway.com/en-us/-/media/northamerica/usa/nutrition/nutritiondocuments/2026/us_nutrition_en_1-2026.pdf" rel="external" data-link-id="subway-nutrition">sufficient caloric content</a> to run a person’s 20-watt brain for a day and a half.</p><p>I wouldn’t consider myself to be somebody you should be turning to if you’re looking for environmental insights. Global energy production and consumption is a whole big thing and frankly I’m probably better off moodwise knowing as little about it as I am practically able to. I will say that it is <em>probably</em> a net negative that AI datacenters use as much power as they do, and it’s <em>probably</em> in our best interests to get that power consumption to go down even if it results in a net decrease in throughput and worse latency.</p><p>What I do feel qualified to comment on is the increase of <strong>entropy</strong> caused by running these systems. I mean this in more than just the strict scientific sense of releasing heat into the environment. I’m also talking about the material that is produced as the stated goal of the whole enterprise—the <em>generative</em> part of generative AI. The text and computer code, the images, the videos—these are increasing the entropy of codebases, the internet, its social spaces, and our own finite attention. As much heat as the servers are venting into the air, at least that much “content” permeates our screens and headphones at the same time.</p><p>Not everybody is okay with that.</p><p>It may or may not surprise you, but I never got into the 3D printing hobby. Don’t get me wrong, it’s an impressive technology and an undeniable boon to tinkerers and professional prototypers alike. My position on it has always been rather pragmatic: I’ve got too much crap in my living spaces—more crap than I have places to put it or the ambition to organize it—so why on earth would I want to own a machine whose sole purpose was to <em>make more crap?</em></p><p>One doesn’t need to make too many mental leaps to draw a parallel between generative AI and 3D printing. You want it, you can have it. It’s pretty cheap, and it doesn’t take anywhere near as long as trying to find somebody to make it for you using the old techniques. If it comes out deformed, throw it away and try again. Nobody put any substantial effort into making it, so it’s not like you’re hurting anybody’s feelings by discarding it. As soon as a new design leaves the machine and you carry it away, you’re holding the only instance of a brand new thing, a bespoke build just for you. That should make you feel… something, right?</p><p>“When you get something for free, it has no value.”<mark class="mn-sn-content side"><em>Tribunal Justice</em>, “The Dumped Dog” (season 1 episode 27)</mark> This line has been spoken—on more than one occasion—by Adam Levy, son of Judge Judy Sheindlin, on the reality court show <em>Tribunal Justice</em>.<mark class="mn-sn-content side">The fact that he made this statement on a free TV show streaming through an app called Freevee is an irony not lost on me.</mark> In the original context, he was explaining why animal rescues charge fees as a kind of filtering mechanism to weed out low-effort adoption attempts. I think about his quote a lot.</p><p>We’ve got a technology here that can produce basically anything that can be represented symbolically—written and spoken language, music, images, video—along with any information that can be encoded within one of those mediums. <mark class="mn-sn-content margin">If it weren’t for limitations in human-computer interfaces, there’s no plausible reason why it couldn’t generate scents and flavors as well.</mark> The price for any of these outputs is, well, whatever AI training and inference goes for these days. It’s apparently cheaper than actually staging a video shoot or bugging your friend to serenade you with a guitar or mustering up the mental wherewithal to write a four-sentence email to your boss or finally learning which order the arguments to the <code>ln</code> command go in. <mark class="mn-sn-content margin">If this is something you regularly struggle with, I’m gonna blow your mind. <code>ln</code> works the same as <code>cp</code>:<br /><code>$ cp WhereItIs WhereYouWantIt</code><br /><code>$ ln -s WhereItIs WhereYouWantIt</code></mark> Why do the difficult, expensive, time-consuming old thing when you could just do the easy, cheap, fast AI thing? In fact, why strive to do anything of value when you could have a passable knockoff for basically free?</p><p>You ever see somebody make a social media post like “Look what I made using AI!” and hardly anybody gives a shit? Perhaps if the work had some value, others would value it more.</p><p>I will concede that it is frankly incredible that we have gotten so close to empirically testing the <a href="https://en.wikipedia.org/wiki/Infinite_monkey_theorem" rel="external" data-link-id="wiki-infinite-monkey-theorem">infinite monkey theorem</a>, and I don’t mean that sardonically. It is a miracle of human ingenuity that we can etch 100 billion transistors onto a piece of rock we dug out of the ground. The fact that we don’t really understand how it works, yet it <em>does</em> work, is astonishing. It’s frighteningly good at search and retrieval. This hardware is capable of doing some genuinely cool stuff that might actually set us up for untold prosperity for generations to come. But if we’re just going to use it to make another lazy Stable Diffusion image of a smooth beige coffee shop or a commit message peppered with green checkbox emoji and a waffling description of the code changes<mark class="mn-sn-content side">“This pull request appears to…” <em>Appears</em> to? You wrote it, my guy!</mark>—all in the hopes that it will make us all a lot of money someday, somehow—just put that rock back where you found it.</p><p>Oh, how about this one: “In order to truly serve you, these systems need to know all there is to know about you.” LOL. It’s like we somehow forgot how to view things through a lens of suspicion.</p><p>We live in a society <em>with other people</em>, and as much as it might be an annoyance sometimes, those other people deserve to enjoy a certain amount of dignity and respect. You’ve got family, coworkers, friends, neighbors; your life is a complex web of social interconnections. You are well within your rights to open your address book, your email archive, your photos and videos up to third-party services to help you manage your life… but did you ever bother to ask if the people represented in that content were okay with you sharing it? Maybe your good friend doesn’t want their name/address/phone number to be given away so hastily. Maybe your coworker would’ve written that off-the-cuff text message a little differently if they knew you were going to ship it off to be summarized and preserved in perpetuity. Maybe you’ve got a family member who thinks it’s downright creepy that there’s a timestamped image of their face along with GPS coordinates nestled away in the EXIF data floating around out there somewhere, just because you snapped an innocent photo at their party and then freely gave it to an amoral technology company. Hooray, you’ve built a digital assistant to help organize your calendar, and now it sees that I responded ‘yes’ to the invitation to be in a place at a time to do a thing. Why does it need to know that about me? May I politely ask you to stop telling it that without my consenting to it?</p><p>Now, let me just nip this one in the bud: I’m going to fucking keelhaul the next person who calls me a Luddite for feeling this way. I’m not arguing that this technology should be unilaterally destroyed; I am arguing that we are collectively using it in the dumbest possible way, causing the most self-inflicted injury, and maximizing the amount of angst and suffering we’ll all have to contend with. I am angry at generative AI because it seems to be making us think and act like complete idiots.</p><p>But if you wanna talk Luddites, here’s something to chew on. The Luddites were 19th-century textile workers who opposed the introduction of machinery that automated what had traditionally been the tedious process of hand-finishing cloth. They didn’t enjoy the tedium <em>per se</em>; what they liked was the ability to earn a livable wage in exchange for <em>enduring</em> that tedium. Part of their argument was, although the machines were touted as being able to do the same job quicker and cheaper, the end product was of inferior quality due to the lack of skilled attention given to the work. They might’ve said that quality was something worth paying a little more and waiting a little longer for. <mark class="mn-sn-content margin">I happen to agree with that, but it doesn’t mean I’m going to get all smashy about it.</mark></p><p>I bet that somewhere in your closet or dresser you’ve got a shirt that you don’t wear anymore. Maybe it was nice when you bought it, but after one or two washes it started to pill, or it faded, or some of the stitching began to unravel. If it looked nicer, maybe you’d donate it to a thrift store. Then again, if it looked nicer you’d still be wearing it regularly. Maybe you should just throw it out; it’s not even the kind of fabric that’s good to wash your car with. You’re not even really mad about it, considering how cheap it was. Maybe you should just leave it where it hangs; that seems like the least sad option.</p><p>Do you ever wonder, had the Luddites not failed, if we’d be so awash in cheap garbage clothing today?</p><p>Is anybody else tired of living in a world filled with abject crap?</p><h2 id="live-work-and-play">Live, work, and play</h2><p>Toby made his first chair when he was twelve years old. It was built from scraps he found behind the barn, some weathered 2×4s and the remnants of a card table. It was a boxy kind of thing, no armrests, and not a single curved surface anywhere on it. But the cuts were square, the pieces fit together well, and it felt like something that might last for a while. He never cared much about the finish, never sanded any of the surfaces, he slathered it in Rust-Oleum red and put it into service at the desk where he did his homework.</p><p>He made another a few weeks later, and gave that one to his granddad as a gift. Pretty much the same design, same color, although this one was a little taller to better suit the recipient’s towering stature. Then he made another one for his best friend to sit on when they hung out.</p><p>In the years since then, Toby’s made more chairs than he can even recall. It’s easily over a thousand at this point. He’s got a whole workshop with a few staff helping him out. And they’ve branched out into other pieces too—end tables and three-shelf bookcases, those kinds of things. Toby’s shop has enjoyed a modest amount of regional fame and there’ve been plenty of orders to keep his crew busy.</p><p>He was recently interviewed by a student for the local middle school’s newspaper. Toby loved talking about his work—evidenced by the joyful smile peeking through his bushy salt-and-pepper beard—and he loved inspiring kids to set ambitious goals in their own lives. When asked what keeps him going, he replied simply: “Every day that I come in here and pick up my tools, I have the opportunity to give somebody in the world a comfortable place to sit.” He actually had to say it twice; the student was not the fastest with a pen and pad.</p><p>Across the shop, Lyle looked up just in time to catch Toby delivering that quote. He had just finished clamping a long wooden dowel into his well-worn lathe and was now hunting around his cluttered workbench for his safety glasses. He bristled slightly at the words his boss was essentially dictating to the kid. This was a wood shop; they made chairs. Ain’t nothing lofty or aspirational about that.</p><p>Lyle found what he was looking for, slipped the glasses over his eyes and flipped the switch on his lathe. The dowel came up to speed rapidly as the din of motor noise surrounded him like an old familiar friend. He picked up his favorite chisel and set to work. Back and forth along the length of the piece, sending swarf and chips of wood fluttering to the shop floor, he molded this raw bit of material into one chair spindle in no time flat. He switched the machine off and lifted his glasses to rest above the hairline of his taut man-bun. The spinning blur of the workpiece slowed, then stopped, and he unclamped it. In its place, a brand new dowel from a small stack. The chair being created here called for nine spindles in total, but he wasn’t counting them. It’d be done whenever the stack ran out.</p><p>If there was an encyclopedia article for “being in one’s element,” the picture would depict Lyle doing this work. Outside of his day job, however, his biggest problem was that he never finished anything. He also never really started anything either. His garage was filled with clutter—lumber for projects he thought he wanted to attempt, scraps of half-cut materials he “might need” for another job, a pile of experimental and practice cuts, and the occasional assembled piece brought 90% of the way to completion and then left to languish under spiderwebs and dust. He had a tendency to only pick up things that allowed him to spend time operating the lathe. Once the task progressed past the point of needing lathe work, his ambition for continuing dropped precipitously. He had at one time semi-seriously considered going into business for himself making custom baseball bats, but the closest potential customer was a low-A ball club about 100 miles away that he never actually worked up the nerve to contact. He didn’t even want that for himself; the world told him that he was supposed to want that.</p><p>In the five or so years he’d worked at the shop, Lyle never really had any lengthy or deep conversions with Toby. They had always been cordial enough—how’s the family, have you ever been camping, can you believe our team blew the playoff game—those types of chats. But nothing more involved than that. Lyle had always respected Toby and the way he chose to run the business, but he never quite wanted to get too into the weeds talking about orders and customer success and <em>vision</em>. That kind of stuff required way too much people-pleasing and time spent talking on the phone for Lyle’s tastes. It was frankly better for everybody that he stayed back behind the lathe churning out chair parts, table legs, even the occasional set of balusters. It was all the same from where he sat.</p><p>One of Toby’s earliest realizations during the infancy of the business was that, although he was skilled enough at every aspect of furnituremaking to build everything himself, he wasn’t passionate about many of the low-level aspects of the work. He’d barely been in business for two months when he hired Beau to take over sanding and finishing—Toby’s least favorite tasks of them all. Janice was hired to do shipping and receiving, another set of responsibilities that he couldn’t stand sacrificing time to. Lyle was probably the fourth or fifth hire once production started seriously picking up. The lathe was Lyle’s whole domain of expertise; he never had the slightest ambition to branch out to anything beyond that single passion. He was a literal <em>artist</em> when it came to turning wood, and Toby appreciated how reliably Lyle’s parts matched and fit together.</p><p>Above all, Toby remained the idea guy. The designer of the various product lines, the head of sales, the one-man public relations department and the self-proclaimed mastermind of the whole thing. He was always full of big ideas and big plans, and they all led steadfastly to a world filled with handcrafted furniture—his name and crest branded on the underside of each piece by Beau’s scorching hot iron. Toby made furniture for everyone and everybody, dammit.</p><p>As far as Lyle was concerned, Toby was a bit of a pompous, self-aggrandizing windbag. His wood shop made chairs, not cancer cures. Still, it was a pretty good gig for this small town on the Appalachian side of the Rust Belt and the work suited him well. All he ever wanted in life was to gradually shape wood into axially symmetric curves and forms. It was the closest thing he ever found to feeling like he had a purpose on this earth. He never even thought too hard about what all those finished pieces ended up going into. He just loved using the lathe, and he was a rare master at it. Lyle was born to be a woodturner, dammit.</p><hr /><p>Not everybody views shipping products as a personal value.</p><p>Here we come perhaps to the meat of why everybody seems to think everybody else is some kind of contemptible fool. People have certain core values—sometimes held subconsciously—and these can seem utterly bizarre to others who don’t share them. I’m starting to believe that many arguments about AI use (and probably a bunch of other things) boil down to people forming opinions and preferences from a set of values and principles that are incompatible with those held by the other party.</p><p>Put simply, Toby deeply values shipping things and providing value to society, and Lyle doesn’t. Lyle values expertise in a skill carried out with utmost care and craft, and Toby doesn’t. Toby’s ultimate dream, beyond the whole furniture thing, is to eventually make enough money—having never completely settled on what nebulous sum of money constitutes “enough” for him—that he can retire into peaceful old age. Lyle wants to keep doing what he does until his body finally gives out, and then to continue doing it for a little while longer. Any discussion between the two of them that brings these incompatible sets of values into tension is going to end up in some kind of argument that neither side will concede. And who would expect them to? These are the very foundations of their personalities.</p><p>This, right here, is why everybody is fighting all the time. We’re all trying to argue positions based on mismatched values. Not <em>wrong</em> values. Mismatched.</p><p>On the one side, you’ve got folks whose entire sense of self-worth and meaning is inexorably tied to the act of generating economic value for the benefit of outside parties. In the other corner, you’ve got people who aren’t primarily focused on creating anything of any appreciable value for others and who are motivated instead by some internal passion or belief. Perhaps they would be more likely to be viewed as selfish or childish for putting their own interests first. Any economic value that the latter group manages to produce is either a useful byproduct of that internal drive or just a straight-up accident.</p><p>Neither of these is <em>wrong</em>.<mark class="mn-sn-content side">Although the former certainly fits into capitalism’s mold a lot more readily.</mark> They are simply <em>different</em>.</p><p>When we visit sites like the LinkedIns or the Hackers News, we’re stepping into environments that are already disproportionately skewed toward the “generate economic value” side. LinkedIn is a venue for cosplaying a character who might be wise or insightful about business and that swole grindset hustle, and Hacker News is an echo chamber for technology enthusiasts who deliberately inserted themselves into orbit around a startup accelerator.<mark class="mn-sn-content side">Y Combinator</mark></p><p>It’s no wonder why a person in the “do what I like” camp might feel alienated and outnumbered in spaces like those. It’s not surprising that voicing an opinion that runs counter to the broad themes of “generate economic value” would sow discord. It doesn’t mean anybody is wrong <em>per se</em>, but it does suggest that somebody should at least try to point out a possible reason why this keeps happening.</p><p>Having said that, as a proud citizen of the “do what I like” tribe, I do feel qualified to point out exactly what bothers <em>me</em> about the other side’s talking points. Feel free to take it or leave it.</p><p>You ever notice how the big selling point of AI is how much more productive it makes everybody? “Saves time,” “Lets me do 10× what I did before,” “I can work on five different things simultaneously,” and so forth. I’m skeptical of the exact numbers—especially that 10× figure—but I’m broadly convinced that the use of AI is actually making some people faster at certain tasks. Sometimes in a moment of vulnerable transparency you’ll hear things like “It makes me <a href="https://siddhantkhare.com/writing/ai-fatigue-is-real" rel="external" data-link-id="siddhantkhare-ai-fatigue">more tired than I used to be</a> at the end of the day.” Sign me up. /s</p><p>You know what I never hear in these discussions? “It makes me <em>happier</em>.” “It gives me a sense of <em>fulfillment</em> and <em>meaning</em>.” “It has provided me with <em>higher income</em> or a <em>shorter workday</em>.” “I am finally <em>respected</em>.” You’d think that if somebody attained these, that would get top billing over some olive-drab tripe about productivity and KPIs… right? Or am I just supposed to take it as implied that productivity naturally and inevitably leads to all those other good things, and clearly we all know this, so why should it need to be stated explicitly?</p><p>I dunno, man. I don’t think I see it.</p><p>Another piece of unpleasantness that I thought we as a species had outgrown involves any metric focused on <strong>lines of code</strong> (LoC). This is a measure of exactly what it sounds like—the number of lines of program code you can scroll through on the screen. We’ve been trying for decades to finally eradicate this profoundly stupid measure of engineering productivity, and now it’s back. Hooray, LLMs can poop out more LoC than humans can. Work harder, not smarter, I guess.</p><p>If you’re working on a software project and you find that the requirements call for there to be 25 whoozits on a particular page of the app, there are (broadly) two ways to achieve that:</p><ul><li>Write the code to add one whoozit, then manually copy-paste it 24 more times.</li>
<li>Write the code to add one whoozit, and enclose it in a looping construct that runs 25 times in total.</li>
</ul><p>The first option requires ≈25 times the LoC compared to the second option. By the way some people are evaluating AI performance, the author of the first option is 25 times more productive. But if you ever find yourself in the position of needing to go back after the fact and change something on all the whoozits, you’d probably appreciate the original author a lot more if they kept things lean and mean with the second, loop-based option.</p><p>“But wait!” Oh, great, <em>this</em> guy again. “AI is the perfect solution here because it does all that rote correction for you! It shouldn’t matter which way the code was structured because coding agents can make the change just as easily either way.” Sure, and if you want to wear clean clothes, you could either do the laundry <em>or</em> you could throw your wardrobe away after one wear and have fresh replacements drop-shipped from China.<mark class="mn-sn-content side">Rob Rhinehart, the mind behind the Soylent meal replacement drink, apparently <a href="https://web.archive.org/web/20151211222101/http://robrhinehart.com/?p=1331" rel="external" data-link-id="robrhinehart-how-i-gave-up-alternating-current">did exactly this</a>. The Luddites would probably have had some choice words for him.</mark> The two approaches are only equivalent to maintain if you are willing to ignore the massive Rube Goldberg machine of complexity that one side requires that the other side doesn’t.</p><p>I don’t know if some people just flat-out don’t understand where care and craft come from. I’m not even sure I can put into words exactly how strongly some of us feel their pull in all facets of our lives. It is kind of like being in a position of being asked by society to fell a metaphorical tree, being given the option of using <a href="https://www.scottsmitelli.com/articles/large-chainsaw-model/">a chainsaw</a> or an axe, and sometimes deliberately choosing the axe despite it being more difficult and time-consuming in every measurable way. I could’ve cut through that trunk easily with the chainsaw, yet I chose to do it the harder way for a reason that was deeply important to me, and I <em>succeeded</em> at it. The tree coming down was the part that was important to society, but the hard axe work was important to <em>me</em>. Any ol’ schmuck could’ve bungled their way through a tree trunk using a chainsaw, but I saw no merit in taking that easier path. <mark class="mn-sn-content margin">Just look at how long this article is, for God’s sake. And you’re just reading it—I made myself <em>write</em> it!</mark> The challenge of doing things the hard way has led me to some of my proudest achievements in life.</p><p>You can perhaps see why I might respond poorly to losing the axe option.</p><p>The act of solving meaningless puzzles can itself be meaningful to individuals who hold challenge or the accumulation of skills and knowledge as core personal values. That is how their reward systems are wired. Burning cycles on a challenging problem with limited-to-no broader practical utility is a noble pastime for them.<mark class="mn-sn-content side">And I guess now I gotta reevaluate my moral objection to the proof-of-work consensus algorithms that the blockchain bros are always touting.</mark> Even mindlessly repetitive work—for instance renaming a file or source code object then patching up all references to the old name to use the new name instead—can serve as an easy brain hack for a quick dopamine hit. Separately from that, the act of manually cleaning up bad patterns reinforces what they look like and might help good patterns stand out by comparison in the future. Sometimes we get sent down a fruitful rabbit hole during one of these mental jaunts, and that can pay dividends later on. <mark class="mn-sn-content margin">That’s what pushed me to sit down and properly learn AWK; I experienced one too many instances of needing to reformat some hideous data and desperately wanted a better way of tackling it. This can backfire, however: I’m sure you have encountered the type of person who appears to spend all their time reinstalling different Linux distributions or endlessly tweaking their Oh My Zsh plugins to no specific end—not even as practice or meditative work. It takes a certain self-awareness to notice the point where pulling a given intellectual thread stops serving a purpose and devolves into aimless fidgeting.</mark></p><p>I travel through the world at speeds exceeding 30 mph all the time and nobody cares. Usain Bolt does it and he gets an Olympic gold medal. The difference is that I use a Toyota, and he uses his freakin’ legs and feet. Are we suggesting he’s wrong for choosing to do something challenging that runs afoul of what society views as maximally efficient?</p><p>“But the company—” Will you shut up. Companies value velocity and new launches and shipping first at all costs because <em>of course they do</em>; it’s table stakes. Speed of delivery is basically the number one corporate value of every organization whether they admit to it or not. They’ll say they value experimentation, but not as much as shipping. Or they’ll claim to be really into investing in people and fostering growth, but not to the extent that it should let the schedule slip. Maybe they’ll say something about embracing failure, unless it’s a failure to get the app redesign in users’ hands before the end of the fiscal quarter. Some places really, really mean it when they say “ship or GTFO,” and those organizations have a tendency to grind employees into dust and then burn the dust for fuel. But going purely on outcomes, it sure seems like most places don’t actually value velocity as much as they claim to, just like all the other corporate values that pad out their Careers page.</p><hr /><p>“Wait a second, I need a pen.” Janice rifled through the top drawer, uncharacteristically frazzled. “Non-ST elevation… myocardial? Speak English!” She was not the type of person to lose her composure on the phone. “Oh my god.”</p><p>Lyle heard the news along with everyone else in the shop: Toby had had what they called a “mini” heart attack and was being treated at the medical center in the city. He was awake and conversational with the nurses, but it could have been much worse under different circumstances. Janice continued her announcement, something about prayers and taking time if you need it, but Lyle retreated inward. A flurry of thoughts ran through his mind.</p><p>Toby was the kind of guy who clearly looked like he took care of himself. He was among the most physically fit people in the shop—built like a tank—probably capable of running a 10K, beating the living hell out of somebody, and eating a tomahawk ribeye all before noon. Still, he was always worked up about something or other, the lines on his furrowed brow permanently etched like carved mahogany, and he never seemed to be completely at peace. As readily as the man laughed at life’s trials and tribulations, the moment the laughter faded there was a palpable worry in his eyes. There was so much he needed to do, never any time to do it, and this little medical setback was probably the last thing he needed right now.</p><p>For no reason that he was able to discern, Lyle remembered his own garage at home. He briefly imagined a world in which he had died unexpectedly and how his family might handle dealing with all of his accumulated junk. He thought about the walls and shelves and piles of stuff he tossed into the attic or basement and how his grieving relatives would have to make all the decisions that he could never bring himself to make in life—what to organize, what to donate, what to save, what to destroy. The idea of forcing the consequences of his own inaction on other people, people he loved, filled him with guilt.</p><p>A second wave of guilt washed over him when he realized that he was now thinking of himself during a time when his friend needed— Wait, was Toby even his friend? They’d worked basically shoulder to shoulder for almost six years… What were they in each other’s view?</p><p>He wasn’t sure which of those thoughts finally did it, but the tears began to well up under his eyes as he returned to his workbench.</p><h2 id="skill-issue">Skill issue</h2><p>Kenny Rogers once sang, and I am paraphrasing a bit, “You got to know when to GPT 5.2 Codex, know when to Gemini 3.1 Pro, know when to Opus 4.6, and know when to DeepSeek V3.” Knowing all the minute differences between all of these models is the key to your success. If you don’t pick the right one for the job, the game is over before it even starts!</p><p>Sometimes it’s better to prompt an LLM to <code>think hard about this</code> explicitly. But other times that irrelevant context messes it up more than if you had left it out. You might occasionally improve a model’s output accuracy by <a href="https://www.theregister.com/2025/05/28/google_brin_suggests_threatening_ai/" rel="external" data-link-id="theregister-sergey-brin-threatening-ai">threatening it</a>. But don’t threaten it so much that it turns around and tries to <a href="https://www.bbc.com/news/articles/cpqeng9d20go" rel="external" data-link-id="bbc-ai-resorts-to-blackmail">blackmail you</a>.</p><p>Sometimes you need “<a href="https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04" rel="external" data-link-id="medium-welcome-to-gas-town">a source form for workflows, Formulas, in TOML format, which are ‘cooked’ into protomolecules and then instantiated into wisps or mols in the Beads database.</a>” <mark class="mn-sn-content margin">Something’s “cooked” alright, and I suspect it’s brains.</mark> You’re using a <strong>reasoning model</strong>, right? You gotta remember to give it enough context. No, <em>way</em> more than that. But stay within your token budget. Keep the important stuff far away from the system prompt at the start of the context window. But also keep it far from the end. Run precisely the correct number of agents at all times. It’s basically a thinking model, if you squint!</p><p>Not everybody wants to keep up with the breakneck pace of industry press releases, social media anecdata, and superstitious horseshit.</p><p>If you didn’t get good results, or the techniques just didn’t work for you, a common retort is that you must’ve done something wrong. You didn’t pick the right model or mode, didn’t include the right shibboleths, something was wrong with the prompt or the context, you didn’t put your <a href="https://en.wikipedia.org/wiki/Rally_cap" rel="external" data-link-id="wiki-rally-cap">rally cap</a> on the right way… It’s gotta be <em>you</em> that’s the problem. Because it works great for everybody else!</p><p>There exists a certain personality type for whom it is very, very important that they are right. But more than that, they need to be <em>seen</em> being right. Their conversations will tend to follow an arc of proclaiming that Thing A is better than Thing B, laying out an extremely detailed case for Thing A, and then waiting around for that setup to pay off by Thing A beating Thing B by some objective metric. When this person is right, it can be a vindicating experience for them. When they are wrong, they’ll tend to suffer a kind of very specific amnesia about what they said or believed in the past.</p><p>It is perhaps similar to the type of person who constructs a whole narrative around the idiotic parlay they just wagered $50 on. If all the legs hit and the bet pays off big, this person will claim that they knew exactly what they were doing and that their analytical skill, deep understanding of the game, and genius-level intuition was what allowed them to see the outcome so clearly. When they lose, however, it’s dismissed as somebody else’s fault—the player choked, the official made a bad call, the field was slick, etc. For these people, betting and winning alone are not enough to bring a sense of satisfaction. They must be <em>seen</em> placing that bet and winning. It is important for bystanders to see that they are Very Smart. <mark class="mn-sn-content margin">The same kind of braggadocio might be seen in a pool player calling a complex shot before sinking it. But the pool player is respectable because it really is their skill that allows them to call a shot and then execute it.</mark></p><p>Betting <em>and winning</em> is hard to do—so some folks simply go all-in on whatever seems to currently be in the process of winning right now.<mark class="mn-sn-content side">This, perhaps, may go a long way toward explaining the relationship that many people now have with national politics in certain countries.</mark> I suspect that a fair chunk of the AI-boosting discourse online isn’t being written by people expressing a sincerely-held belief or opinion about anything pertaining to AI itself, but rather by people who want something they can point back to when/if AI takes over the world so they can say, “Look, I knew it was going to happen and then it happened! I am Very Smart indeed!”</p><p>Occasionally you’ll get the person who claims that one of the models was able to completely reimplement an entire piece of obscure software from nothing but three screenshots of its UI. This will come with fanciful claims like a full test suite or, my personal favorite, complete binary compatibility with the data file format that the original software produced. “May I see it?” the reply asks with an almost <a href="https://www.youtube.com/watch?v=4jXEuIHY9ic" rel="external" data-link-id="youtube-steamed-hams">Superintendent Chalmers–like sincerity</a>. “You just gotta try it yourself. Come up with an idea, just prompt something on your own. Join us.”</p><p>You know what else people will do when they want to appear like they’re cool or smart? They’ll <em>lie</em>. It’s like we somehow forgot about the very first row of the Periodic Table of Human Social Behaviors.</p><p>I was eleven years old and in elementary school when <em>South Park</em> first aired. As far as I could tell, every kid in the class was watching it except for my sheltered ass. But I wanted to seem cool and part of the “in” group, which led to my contributing the following one-half of a conversation: “Yeah, I saw <em>South Park</em> last night… Oh yeah, that was mad funny… Mm-hmm, I love Carmen too. She’s probably my favorite.” <mark class="mn-sn-content margin">About two years later, having learned nothing from this experience, I had substantially the same conversation regarding Eminem.</mark> For the life of me I can’t remember who I said that to, but I clearly remember saying it.</p><p>Carl Sagan is quoted as saying “extraordinary claims require extraordinary evidence.” I bet he never fabricated a story about watching a cartoon show to fit in with a bunch of kids who were probably also lying about having seen it.</p><h2 id="reimplementing-the-wheel">Reimplementing the wheel</h2><p>Here’s a question that I don’t think anybody would be able to even estimate an answer to: How many different implementations of a login page do you suppose humanity has collectively written?</p><p>Consider every website that ever made you register an account using a user name and a password. Some of them offer single sign-on with services like Google or Facebook, but they’ll generally have some kind of password fallback for people who don’t have or don’t want to use those services. Some will send two-factor codes via SMS,<mark class="mn-sn-content side">And I hate that they do.</mark> others send a “magic” sign-in link to an email inbox. Some integrate with biometric authentication devices, and others think that security questions and ridiculous password restrictions are still really swell ideas. They’ll all gladly send you a password reset email that expires in ten minutes and arrives in twelve.</p><p>How many development teams sat down and, as one of the first tasks in the creation of a greenfield project, built and tested yet another user registration and login/logout flow? How many of these login pages are essentially identical, independently created in isolated vacuums, and jealously guarded as priceless nuggets of intellectual property by the organizations that commissioned them? Why is writing a login page such a universally shared experience that it has been immortalized in the lyrics of a <a href="https://www.youtube.com/watch?v=AEBld6I_AKs" rel="external" data-link-id="youtube-code-monkey">Jonathan Coulton song</a>? Who sits down first thing in the morning with a cup of coffee and says, “Oh boy, today I get to write a login page!”</p><p>In other engineering disciplines, the kinds where you have to behave like a credentialed adult at work, there are standards bodies that assemble volumes upon volumes of knowledge about the professionally accepted ways of doing things. If you wanna run a beam from here to there made out of such-and-such material, it can hold this much weight. This is the bolt to fasten it with, and here is the torque specification. Stay within the parameters and it’s unlikely the structure will fall down. These standards are written by some of the most experienced and knowledgeable people on the topics, and deviating from them is a surefire way to build something that will eventually be described using the word ‘boondoggle.’</p><p>The computer industry actually does have standards bodies, if you can believe that. These tend to focus on hardware and networking layers, and thanks to these standards you can be reasonably sure that any gadget you might buy will successfully connect to your Wi-Fi network or pair with your Bluetooth speaker. Thanks to things like the USB-C standards, we’re starting to no longer need to worry about which charger came with which device anymore. Standards made that possible.</p><p>Software, on the other hand, can be a total free-for-all. Wanna write a login page? Only a fool would build one from scratch; better to find an existing open-source library that does the heavy lifting. You could head over to npm and browse through <a href="https://www.npmjs.com/search?q=login" rel="external" data-link-id="npm-search-login">the 1,000+ projects that match the search term <code>login</code></a>. Or bop on over to PyPI and spend some time examining <a href="https://pypi.org/search/?q=login" rel="external" data-link-id="pypi-search-login">10,000+ of them</a>. Why has nobody developed <a href="https://xkcd.com/927/" rel="external" data-link-id="xkcd-standards">one universal standard that covers everyone’s use cases</a>?</p><p>You won’t need to go around on the corporate merry-go-round for too long before encountering a certain type of engineer. This person tends to score closer to the “do what I like” end of the spectrum, which wouldn’t be so bad if they weren’t also a narcissistic man-child. This is the type of person for whom no existing solution is adequate, so only a custom build will solve the challenging needs of the business. It will adhere to modern best practices and repeat no past mistakes, be built from the freshest technology containing no legacy baggage, it will be <em>grand</em> and <em>complicated</em> and it will <em>succeed</em> and look good on their <em>résumé</em>. These are the kinds of people who fancy themselves as a Ken Thompson, Rob Pike, or Steve Wozniak—creating something novel and important to humanity—when in reality they’re just a garden-variety engineer, good enough at what they do to make a not-as-good version of something that already exists. Management permits this work, at least in places where management doesn’t know to question the intentions. <mark class="mn-sn-content margin">Or when the engineer in question throws a calculated tantrum and threatens to leave if they don’t get their way.</mark></p><p>AI assisted coding—and particularly <strong>vibe coding</strong>, where all development occurs via prompting and the underlying code is not reviewed at all—ticks a lot of these same boxes. If the person prompting the LLM needs a not-as-good clone of something that’s been done a thousand times before, bam, there it is. Why do they need it? Doesn’t matter, there it is. The prompter has now assumed the role of the manager who can’t see if or how their subordinate might be distorting the facts of the project’s implementation.</p><p>If they wanna be a manager like that, they should just go into management. It almost certainly pays better.</p><p>In his essay “<a href="https://darioamodei.com/essay/machines-of-loving-grace" rel="external" data-link-id="darioamodei-machines-of-loving-grace">Machines of Loving Grace</a>,” Anthropic CEO Dario Amodei lays out his visions of the role humanity will play in an age of what he calls “powerful AI.” <mark class="mn-sn-content margin">He goes out of his way to <em>not</em> call it “artificial general intelligence” because that would send an unwelcome Google Alert to his investors, or something.</mark> He rejects the notion that these systems will be relegated to chewing through data looking for patterns, and instead proposes a future where the AI calls the shots and humans are akin to its graduate students. That’s what he said; those were his actual words:</p><blockquote>
<p>If our core hypothesis about AI progress is correct, then the right way to think of AI is not as a method of data analysis, but as a virtual biologist who performs all the tasks biologists do, including designing and running experiments in the real world (by controlling lab robots or simply telling humans which experiments to run – as a Principal Investigator would to their graduate students), inventing new biological methods or measurement techniques, and so on.</p>
<footer>Dario Amodei, “Machines of Loving Grace”</footer></blockquote><p>Ah yes, that most sought-after career, <em>graduate student</em>. Can’t wait to spend my stipend on a pallet of Cup Noodles and a car with hand-crank windows.<mark class="mn-sn-content side">I do unironically enjoy cars with window cranks as a nostalgia thing, but I also like having choice in the matter.</mark> How can both of these visions of the future be true? How are humans supposed to orchestrate massive swarms of agentic AI to do all their bidding while simultaneously following the orders of the big boss AI as it demands that they stir some stuff in a flask? Which of these two camps is wrong? Who is the liar here?</p><p>Personally, I don’t know how to fix the software engineering profession because I can’t even articulate exactly what’s broken about it. But I think that the insistence on continually yelling “build, build, build!” while producing exactly the same thing that countless organizations have already built and hoarded for seemingly no reason is a fairly important symptom.</p><p>“Code is our most valuable asset, but also our biggest liability in terms of maintenance burden.” “The code is proprietary and secret and must never leak, so we install a device management profile that disables everybody’s USB ports. But we also require all staff to upload the entire codebase to the hosted model <em>du jour</em> so that it can make even more code that we don’t read or value.” “Slap a copyright notice on every file, despite the fact that LLM output is <a href="https://en.wikipedia.org/wiki/Monkey_selfie_copyright_dispute" rel="external" data-link-id="wiki-monkey-selfie-copyright-dispute">probably not actually copyrightable</a>.” “<em>Our</em> product is superior to our competitors’ because <em>we</em> were the ones who vibed it into being instead of them.” This industry seems manifestly sick.</p><p>If AI coding assistants can do a task well, it probably isn’t a novel task. Why have we set things up in such a way that we need to expend so much time and energy doing <a href="https://www.scottsmitelli.com/articles/altoids-by-the-fistful/">the same thing</a> over and over without contributing the fruits of those efforts back to the commons? Why is “paying it forward” such a nonstarter to companies who got where they are on the backs of open-source developers who paid it forward in their own time? Why was <a href="https://github.com/drathier/stack-overflow-import" rel="external" data-link-id="stack-overflow-import-source"><code>from stackoverflow import quick_sort</code></a> a joke somebody made instead of a sincere attempt at improving engineering standards?</p><p>The next time you find yourself in a coding interview being asked to solve some problem that somebody else already solved, pause to consider if part of what they’re testing for is your ability to not let that bother you. Maybe they want to ensure that their potential hires don’t yearn to be somebody more, doing something better, as those kinds of candidates might be perceived as flight risks.</p><p>The loading spinner covering the greyed-out login form appears, disappears, reappears, and disappears again. Behind the scenes an OIDC grant is handed off to the legacy SAML provider, which redirects through YouTube despite that acquisition happening 19 years ago, then via XML-RPC to a COBOL program that is only spoken of in reverent whispers. At every layer of the stack, nobody knows what’s going on.</p><h2 id="so-no-one-told-you-life-was-gonna-be-this-way">So no one told you life was gonna be this way</h2><p>Not everybody wants to choose between “adapt or get left behind.”</p><p>Perhaps we are indeed facing a fundamental shift in labor on a scale not seen since the Industrial Revolution. If so, the worker pool must upskill, reskill, uproot, reinvent, and it will all work itself out… eventually. That’s not much solace when you’re 40 years old, 40% of the way through your working years, facing the existential threat of having entire sectors of the workforce vanish in the span of a few quarters. What is a person supposed to do <em>right now</em>, prepare to spend the next 10,000 hours as an electrician’s apprentice? Will the banners hanging over the for-profit bootcamps be hastily modified to say “Learn to <del>code</del> weld!” Will I find myself driving from town to town in a work van, rebalancing garage doors or doing warranty repairs on major appliances? How many of us will be competing for that job, anyway?</p><p>This issue cuts through basically the entire white-collar economy to a certain extent—from programming to publishing and government to graphic design. The specifics of each case are different, but the themes are quite similar. It’s demoralizing to spend all day around people—ostensibly peers—and hearing them proclaim that they fundamentally don’t respect the thing you have devoted your professional life to. It’s basically impossible to feel a sense of psychological safety when higher-ups all appear to be eyeing ways to devalue your skills. It’s hard to plan for the future when the entire trajectory of that future rests in the hands of <a href="https://en.wikipedia.org/wiki/Marissa_Mayer" rel="external" data-link-id="wiki-marissa-mayer">some yahoo</a> who views their fellow humans with contempt by default.</p><p>I don’t actually believe that AI is coming for everybody’s jobs, by the way. I rather believe that <em>greed</em> and <em>mismanagement</em> are coming for the jobs, and that workers are being laid off as a direct consequence of leadership failures. AI is simply a convenient smokescreen for these feckless cowards to hide behind. See, if a CEO announces layoffs because the company’s earnings are in the toilet, that CEO looks incompetent. If a CEO announces a <em>reallocation of resources</em> to better leverage the rapidly evolving landscape of workplace automation and AI, they sound Very Smart. Who doesn’t want to sound Very Smart? Here’s your token budget, now go do three people’s work.</p><p>As much as movies and other narrative works would make you believe otherwise, a person’s life doesn’t hinge on any single pivotal decision that permanently makes or breaks their future. What it does have is a constant stream of hundreds of tiny decisions made over the course of each day that move the person slightly closer or further from their goals. These micro-decisions often require very little consideration to make, they are often trivially reversible, and they are generally insignificant in the long run.</p><p>Choosing to embrace or reject AI for any given task is not an irreversible decision. You could try to ignore everything about it until you feel it’s time to change your mind, cram real hard for a few days, and come out ahead of the median employee. <mark class="mn-sn-content margin">This is approximately how I learned systemd.</mark> I know you are capable of this, because—among other things—you had the attention span to get this far into the article. Our choices about AI today are not a “last helicopter out of Saigon” type of situation. You don’t have to listen to people who want you to do something you’re not ready to do yet. <mark class="mn-sn-content margin">If somebody at work is scrutinizing your AI engagement metrics, you can use tokens without <em>using</em> the tokens, if you know what I’m saying. Log file analysis, as one example, can get a person pretty dang high on a usage leaderboard.</mark> There are still engineers out there who are choosing to wait and see where this roller coaster ultimately goes.</p><p>If it’s not painfully obvious from everything I’ve written here, I do not use AI coding assistants. For a while I steadfastly refused to use any LLM at all, but I have softened my stance since then. I came to the realization that, for most of my career, I was perfectly okay with typing a search query into Google, clicking the first Stack Overflow result, and copy/pasting a few lines of code from the highest-voted answer on the page. I would still take the time to try to understand how that code worked, adjust it to match my own style and program flow, and felt no shame in having done any of that. It was indeed faster than trying to find the information in the source documentation.</p><p>That’s not so different from typing the same query into ChatGPT and copy/pasting a few lines of code from its response. It takes about the same amount of time and effort, it doesn’t appear to make me any lazier or dumber, and since I never fully trusted anything I read on Stack Overflow I was well primed to scrutinize the model’s possibly-hallucinated answers in the same way. Once I warmed up to doing this, I started preferring ChatGPT to Google and Stack Overflow for certain kinds of queries. I suppose I’m causing a kind of harm to Stack Overflow by no longer giving them the traffic—and that harm is augmented by the fact that ChatGPT was trained to produce its responses by aggressively scraping Stack Overflow answers <em>en masse</em>—but I would be more sympathetic to the site’s plight if their moderators and power users hadn’t spent fifteen years making me feel unwelcome for daring to ask bad questions in good faith.</p><p>If your only use of AI today is “Google Search but it works,” I am certainly in no position to criticize.</p><p>AI may very well be a clear and obvious strategy to break myself out of lifelong self-defeating patterns of never starting and never finishing things. But at the same time, it may blow right past a legitimate <em>reason</em> why I stand in my own way sometimes. My quirks regarding productivity may be part of a self-regulating mechanism—by requiring significant effort to implement an idea, it ensures that only ideas meeting a high enough standard of quality make it to the development or completion stages. I would much rather make one good thing than dozens of pieces of throwaway junk. And I would much rather live in a world where I am held accountable for my actions and decisions, rather than always running back to an LLM to clean up a mess that I shouldn’t have allowed myself to create in the first place.</p><p>Perhaps I should open my mind to the next logical step, which I suppose would be having an LLM review my code to find potential bugs or edge cases that I hadn’t considered. Personally, I’m not there yet, for a multitude of reasons that I’ve touched on throughout this article. Mostly, I think I don’t want to risk becoming dependent on it, to start getting sloppy in my work with the assumption that the AI will catch whatever I missed, because I’m still not convinced that what we have today is always going to be available in an affordable and <em>useful</em> form once things in the industry aren’t so frothy. When the world feels more stable, I suppose I’ll give it another look.</p><p>And that is perfectly okay.</p><p>You’re allowed to change your mind in the future. If the AI landscape changes, if your personal circumstances change, if you manage to find a balance that feels right to you, there is no shame in saying “I thought that then, and I think something else now.” That’s a measure of personal growth, which seems to be a foreign concept to some people. If you’re not embarrassed by something you believed in the past, you’re not growing.</p><p>The day may come when I look back on this article and feel a deep sense of shame for the person I used to be. Perhaps some of this is overly critical or even cynical,<mark class="mn-sn-content side">More than that, I’m pretty sure a lot of this stuff is <em>actual</em> Cynicism—the ancient Greek philosophy.</mark> but that’s how I currently see it. I primarily wrote this to make sense of my own thoughts, and to try to figure out how a person like myself might navigate some seemingly rough waters ahead. It’s pretty unlikely that I’ll ever want to point back here and say “Aha! I was right! I am Very Smart for thinking and saying that!” I don’t want to be right; I just want to be happy.</p><p>I do think it’s a real shame to paper over all forms of human expression with something that is decidedly not human and isn’t even fun to consume or engage with. Would it be nice if all this stuff shrank back to a reasonable scale, didn’t suck all the oxygen out of every conversation, didn’t send shock waves through global economies, and wasn’t rife with grifters and assholes? Certainly. Will we get to wherever we’re ultimately going in a gentle, orderly fashion? Hell if I know. It’d sure be nice if we could.</p><p>The one thing I know is that I’m no longer willing to listen to those who want to tell me that my values are flawed or my way of being is wrong. I don’t think you should either, if that is how you feel about it. So, you hereby have my permission to keep doing what you’re doing (or not doing). I will caution, however, that not every peer, manager, or employer understands and agrees with this. So you might eventually find yourself having to make a decision or two, and that can feel consequential and scary. I won’t tell you what to do, aside from this one thing: Don’t doubt yourself.</p><h2 id="keep-the-axe-in-the-toolbox">Keep the axe in the toolbox</h2><figure><picture><source srcset="/articles/you-dont-have-to/conclusion.avif" type="image/avif" /><source srcset="/articles/you-dont-have-to/conclusion.png" type="image/png" /><img src="https://www.scottsmitelli.com/articles/you-dont-have-to/conclusion.png" width="1540" height="948" alt="As an experiment, I asked ChatGPT to finish this article. It produced 716 words, including six instances of the word ‘drift[ing]’, which it evidently thought was important to include despite that word appearing nowhere else in the document. The text it produced wasn’t exactly bad, but it did feel deeply unsatisfying. (source)" /></picture><figcaption>As an experiment, I asked ChatGPT to finish this article. It produced 716 words, including six instances of the word ‘drift[ing]’, which it evidently thought was important to include despite that word appearing nowhere else in the document. The text it produced wasn’t exactly <em>bad</em>, but it did feel deeply unsatisfying. (<a href="https://www.scottsmitelli.com/articles/you-dont-have-to/conclusion-original.txt">source</a>)
</figcaption></figure><p>Yeah, I think I’ll stick with my own voice, at least for the time being.</p><hr /><p>I did want to take a moment to thank everybody who talked with me as I was compiling my thoughts on these topics. I won’t list every name because I’m sure I’ll omit somebody and offend them, so instead I’ll omit and offend everybody all at once. But just know that I’m genuinely grateful to each and every one of you for sharing your insights, and I hope I took from those conversations what you hoped I would.</p><a href="https://www.scottsmitelli.com/articles/" title="Articles" class="back-link">« Back to Articles</a>]]></description>
      <link>https://www.scottsmitelli.com/articles/you-dont-have-to/</link>
      <guid>https://www.scottsmitelli.com/articles/you-dont-have-to/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[I paired NotebookLM with Claude Code, and it feels like a dream team]]></title>
      <description><![CDATA[<div class="heading_image responsive-img img-size-heading-image-full-width expandable" data-img-url="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg" data-modal-id="single-image-modal" data-modal-container-id="single-image-modal-container" data-img-caption="&quot;&quot;" data-is-feature-img="true"><picture><source media="(max-width: 480px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg?q=49&amp;fit=crop&amp;w=480&amp;h=270&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg?q=49&amp;fit=crop&amp;w=480&amp;h=270&amp;dpr=2" /><source media="(min-width: 481px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg?q=49&amp;fit=crop&amp;w=1600&amp;h=900&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg?q=49&amp;fit=crop&amp;w=1600&amp;h=900&amp;dpr=2" /><img width="1600" height="900" alt="noterbooklm and claude code on mac" data-img-url="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg?&amp;fit=crop&amp;w=1600&amp;h=900" src="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/noterbooklm-and-claude-code-on-mac.jpg?&amp;fit=crop&amp;w=1600&amp;h=900" /></picture></div><section id="article-body" class="article-body valnet-segment-Software" itemprop="articleBody"><div class="content-block-regular">
<p>A pattern you've likely noticed with AI tools is that a lot of them seem to come and go. One day, an AI tool is all over social media and everyone seems to be using it. The next, the hype has already moved on to something else. It's just how the tech industry in general seems to move. New models drop, new features launch, and suddenly the tool everyone was talking about last month is barely being mentioned anymore. However, in all this chaos, there's always the occasional tool that quietly sticks around.</p>
<p>For me, it was first Google’s NotebookLM. Still <a href="https://www.xda-developers.com/notebooklm-changed-view-of-ai/" target="_blank">hands-down my favorite tool</a>, and I almost always only have good things to say about it. The other tool I've found myself <a href="https://www.xda-developers.com/i-was-wrong-about-claude-and-i-think-you-are-too/" target="_blank">turning back to a lot lately is Claude</a>, more specifically its Claude Code feature. Individually, both are simply incredible at what they do. But recently, I started pairing them together, and that's when things started getting really interesting.</p>
<h2 id="on-the-surface-claude-code-and-notebooklm-have-nothing-in-common">On the surface, Claude Code and NotebookLM have nothing in common</h2>
<h3 id="vastly-different-tools-surprisingly-powerful-together">Vastly different tools, surprisingly powerful together</h3>
<div class="body-img landscape responsive-img image-expandable img-article-item c4"><picture><source media="(max-width: 480px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=500&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=500&amp;dpr=2" /><source media="(max-width: 767px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=800&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=800&amp;dpr=2" /><source media="(max-width: 1023px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" /><img width="1650" height="1100" alt="claude code on mac" data-img-url="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" src="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/02/claude-code-on-mac.jpeg?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" class="img-brightness-opt-out" /></picture></div>
<p>On the surface, Claude Code and NotebookLM have nothing in common. A few days ago, I wrote about pairing NotebookLM and Claude. In that piece, I mentioned how the <a href="https://www.xda-developers.com/replaced-my-single-ai-workflow-with-claude-and-notebooklm/" target="_blank">two tools cover each other's blind spots</a>. However, that was when I was talking about Claude on its own. Claude Code, though, is something else.</p>
<p>It's primarily positioned as a developer tool (though it's an <a href="https://www.xda-developers.com/claude-code-isnt-just-for-developers/" target="_blank">excellent tool for non-developers</a>), lives in the terminal, and is built for a completely different kind of workflow. It's used for writing and modifying code, navigating projects, and automating development tasks directly from the command line.</p>
<p>Unlike regular Claude, which you can technically mold into doing NotebookLM-like things if you structure your prompts and context carefully, Claude Code isn't meant for that kind of use. NotebookLM is built for working with the sources you upload and helping you make something of them.</p>
<p>Claude Code, on the other hand, is built for interacting with codebases. Interestingly, those two very different purposes complement each other incredibly, and that's exactly what makes pairing the two so effective.</p>
<h2 id="notebooklm-is-the-best-way-to-understand-your-codebase">NotebookLM is the best way to understand your codebase</h2>
<h3 id="the-missing-step-in-every-vibe-coding-workflow">The missing step in every vibe-coding workflow</h3>
<div class="valnet-gallery images-count-5 article__gallery type-gallery">
</div>
<p>If you're <a href="https://www.xda-developers.com/vibe-coding-is-the-most-fun-way-to-build-with-ai/" target="_blank">using Claude Code to vibe-code like I am</a>, you likely know how easy it is to let it run with something and suddenly have no idea how half of it works. Before you know it, you're left with a codebase you can barely explain to yourself. I've <a href="https://www.xda-developers.com/used-vibe-coding-to-learn-programming-worked-better-than-any-course/" target="_blank">been leveraging vibe-coding to actually learn the fundamentals of programming</a>, and NotebookLM has been the best way I've found to keep up with my own code.</p>
<p>The best part about NotebookLM is that it's grounded in the sources you upload. For instance, when you upload a README or any file to Claude, it uses it as additional context. This means Claude can still inherently draw on its broader training data to fill in the gaps, make assumptions, or simply make up information.</p>
<p>That's where the issue of AI confidently answering something about your codebase that isn't actually in the documentation comes in — what we formally refer to as hallucination. On the other hand, when you upload a file to NotebookLM, it only uses it to answer your questions. If the answer isn't in your docs, it'll tell you straight up rather than invent something. That's what makes it a much safer layer for codebase Q&amp;A specifically.</p>
<p>Something I've been doing at the end of my vibe-coding sessions is asking Claude Code to generate an in-depth README file that covers everything in the project — how the different files connect, what each part of the code does, and why certain decisions were made. I then drop that README, along with the rest of the project files, into NotebookLM.</p>
<p>From there, I can ask questions about the codebase, trace how different parts interact, and slowly build a clearer mental model of what I've actually built. It's like having a junior developer who knows your project inside and out and can answer any question about it without ever making anything up.</p>
<h2 id="notebooklm-is-the-best-way-to-digest-technical-docs-before-you-build">NotebookLM is the best way to digest technical docs before you build</h2>
<h3 id="read-the-docs-without-actually-reading-the-docs">Read the docs without actually <em>reading</em> the docs</h3>
<div class="body-img landscape responsive-img image-expandable img-article-item c5"><picture><source media="(max-width: 480px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=500&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=500&amp;dpr=2" /><source media="(max-width: 767px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=800&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=800&amp;dpr=2" /><source media="(max-width: 1023px)" data-srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" srcset="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" /><img width="1650" height="902" alt="notebooklm mind map about spotify api" data-img-url="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" src="https://static0.xdaimages.com/wordpress/wp-content/uploads/wm/2026/03/notebooklm-mind-map-about-spotify-api.png?q=49&amp;fit=crop&amp;w=825&amp;dpr=2" class="img-brightness-opt-out" /></picture></div>
<p>Like I mentioned above, when you're vibe-coding, it's incredibly easy to get lost in the weeds and let Claude Code do all the heavy lifting. My aim, even when AI-assisted coding, is to make sure I actually learn something along the way and not just churn out working code.</p>
<div class="w-promotion-offer promo-article-content-3/4-depth w-promotion-widget is-hidden promotion-offer-box" data-popup="false" data-sentinel-tracking="false" data-promotion-zone="TmV3c2xldHRlciBBcnRpY2xlIENvbnRlbnQgV2lkZ2V0" data-nosnippet="">
<div class="newsletter-promotion-large newsletter-section" data-guid="1707177960nlp" data-nosnippet="">
<h3 class="form-section-title">Subscribe to the newsletter for practical AI coding tips</h3>
<div class="newsletter-content-select newsletter-content-element"><input class="cta-mailingList" id="mailingList-36" name="mailingList[]" type="checkbox" value="36" checked="checked" hidden="hidden" /><div class="label-desc">Want deeper guidance? Subscribe to the newsletter to explore practical deep-dives on pairing Claude Code and NotebookLM, with hands-on walkthroughs, curated examples, and targeted explanations that help you understand and work confidently with AI-assisted codebases.</div>
</div>
<hr class="divider" /><div class="w-input-group">
<div><input id="email" class="user-form-input" maxlength="4000" name="email" placeholder="Email Address" required="required" type="email" /></div>
<button class="valnet-newsletter-btn" id="SubmitButton" name="SubmitButton" type="submit" value="Subscribe">Get Updates</button></div>
<div class="form-group"><input type="hidden" id="recaptcha-token" name="recaptcha_token" /><div class="form-notes bottom-note">By subscribing, you agree to receive newsletter and marketing emails, and accept our <a href="https://www.valnetinc.com/en/terms-of-use" rel="noopener noreferrer" target="_blank">Terms of Use</a> and <a href="https://www.valnetinc.com/en/privacy-policy" rel="noopener noreferrer" target="_blank">Privacy Policy</a>. You can unsubscribe anytime.</div>
</div>
</div>
</div>
<p>Before I start a new project or integrate a new tool, I upload the official documentation, API references, or any relevant technical guides into a NotebookLM notebook first. Instead of skimming through pages of dense docs and hoping something sticks, I can just ask NotebookLM to explain exactly what I need to know in plain language.</p>
<p>I also use NotebookLM's different learning features, like <a href="https://www.xda-developers.com/ways-i-use-notebooklms-mind-maps/" target="_blank">Mind Maps</a> and <a href="https://www.xda-developers.com/notebooklm-audio-workflows/" target="_blank">Audio Overviews</a>, to absorb the material in whichever way works best at the time. If I'm away from my desk, on a walk, or commuting, an Audio Overview lets me get up to speed on an API or framework just by listening.</p>
<p>If I need to understand how different parts of a system connect before I start building, a Mind Map gives me the big picture at a glance. This way, by the time I open Claude Code, I actually know what I'm asking it to build.</p>
<h3 id="claude-code-x-notebooklm-is-the-ultimate-coding-duo">Claude Code x NotebookLM is the ultimate coding duo</h3>
<p>I'm always looking for ways to improve my coding workflow, and with vibe-coding, I've noticed that it's very easy to get lost in the details and let the AI do most of the work. Adding NotebookLM into the mix has been an excellent way to actually keep my learning going, letting me understand the code, trace how different parts interact, and build a stronger grasp of the projects I’m working on.</p>
</div>
</section>]]></description>
      <link>https://www.xda-developers.com/paired-notebooklm-with-claude-code/</link>
      <guid>https://www.xda-developers.com/paired-notebooklm-with-claude-code/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Two Years of Emacs Solo: 35 Modules, Zero External Packages, and a Full Refactor | Rahul's Blog]]></title>
      <description><![CDATA[<p>I've been maintaining <a href="https://github.com/LionyxML/emacs-solo">Emacs Solo</a> for a while now, and I think it's time to talk about what happened in this latest cycle as the project reaches its two-year mark.</p><p>For those who haven't seen it before, Emacs Solo is my daily-driver Emacs configuration with one strict rule: <strong>no external packages</strong>. Everything is either built into Emacs or written from scratch by me in the <code>lisp/</code> directory. No <code>package-install</code>, no <code>straight.el</code>, no <code>use-package :ensure t</code> pointing at ELPA or MELPA. Just Emacs and Elisp. I'm keeping this post text only, but if you'd like to check how <code>Emacs Solo</code> looks and feels, the repository has screenshots and more details.</p><p>Why? Partly because I wanted to understand what Emacs <em>actually</em> gives you out of the box. Partly because I wanted my config to survive without breakage across Emacs releases. Partly because I was tired of dealing with package repositories, mirrors going down in the middle of the workday, native compilation hiccups, and the inevitable downtime when something changed somewhere upstream and my job suddenly became debugging my very long (at the time) config instead of doing actual work. And partly, honestly, because it's a lot of fun!</p><p>This post covers the recent refactor, walks through every section of the core config, introduces all 35 self-contained extra modules I've written, and shares some thoughts on what I've learned.</p><p>Now, I'll be the first to admit: this config is <em>long</em>. But there's a principle behind it. I only add features when they are not already in Emacs core, and when I do, I try to build them myself. That means the code is sketchy sometimes, sure, but it's <strong>in my control</strong>. I wrote it, I understand it, and when it breaks, I know exactly where to look. The refactor I'm about to describe makes this distinction crystal clear: what is "Emacs core being tweaked" versus what is "a really hacky outsider I built in because I didn't want to live without it".</p><hr /><h2>The Refactor: Core vs. Extras</h2><p>The single biggest change in this cycle was <strong>architectural</strong>. Emacs Solo used to be one big <code>init.el</code> with everything crammed together. That worked, but it had problems:</p><p>— It was hard to navigate (even with <code>outline-mode</code>)</p><p>— If someone wanted just one piece, say my Eshell config or my VC extensions, they had to dig through thousands of lines</p><p>— It was difficult to tell where "configuring built-in Emacs" ended and "my own hacky reimplementations" began</p><p>The solution was clean and simple: <strong>split the config into two layers</strong>.</p><h3>Layer 1: <code>init.el</code> (Emacs core configuration)</h3><p>This file configures <em>only</em> built-in Emacs packages and features. Every <code>use-package</code> block in here has <code>:ensure nil</code>, because it's pointing at something that ships with Emacs. This is pure, standard Emacs customization.</p><p>The idea is that <strong>anyone can read <code>init.el</code>, find a section they like, and copy-paste it directly into their own config</strong>. No dependencies. No setup. It just works, because it's configuring things Emacs already has.</p><h3>Layer 2: <code>lisp/</code> (Self-contained extra modules)</h3><p>These are my own implementations: replacements for popular external packages, reimagined as small, focused Elisp files. Each one is a proper <code>provide</code>/<code>require</code> module. They live under <code>lisp/</code> and are loaded at the bottom of <code>init.el</code> via a simple block:</p><p>If you don't want one of them, just comment out the <code>require</code> line. If you want to use one in your own config, just copy the <code>.el</code> file into your own <code>lisp/</code> directory and <code>require</code> it. That's it.</p><p>This separation made the whole project dramatically easier to maintain, understand, and share.</p><hr /><h2>The Core: What init.el Configures</h2><p>The <code>init.el</code> file is organized into clearly labeled sections (using outline-mode-friendly headers, so you can fold and navigate them inside Emacs). Here's every built-in package and feature it touches, and <em>why</em>.</p><h3>General Emacs Settings</h3><p>The <code>emacs</code> use-package block is the largest single section. It sets up sensible defaults that most people would want:</p><p>— Key rebindings: <code>M-o</code> for <code>other-window</code>, <code>M-j</code> for <code>duplicate-dwim</code>, <code>C-x ;</code> for <code>comment-line</code>, <code>C-x C-b</code> for <code>ibuffer</code></p><p>— Window layout commands bound under <code>C-x w</code> (these are upcoming <strong>Emacs 31</strong> features: <code>window-layout-transpose</code>, <code>window-layout-rotate-clockwise</code>, <code>window-layout-flip-leftright</code>, <code>window-layout-flip-topdown</code>)</p><p>— Named frames: <code>C-x 5 l</code> to <code>select-frame-by-name</code>, <code>C-x 5 s</code> to <code>set-frame-name</code>, great for multi-frame workflows</p><p>— Disabling <code>C-z</code> (suspend) because accidentally suspending Emacs in a terminal is never fun</p><p>— Sensible file handling: backups and auto-saves in a <code>cache/</code> directory, <code>recentf</code> for recent files, clean buffer naming with <code>uniquify</code></p><p>— Tree-sitter auto-install and auto-mode (<code>treesit-auto-install-grammar t</code> and <code>treesit-enabled-modes t</code>, both Emacs 31)</p><p>— <code>delete-pair-push-mark</code>, <code>kill-region-dwim</code>, <code>ibuffer-human-readable-size</code>, all the small quality-of-life settings coming in Emacs 31</p><h3>Abbrev</h3><p>A full abbrev-mode setup with a custom placeholder system. You define abbreviations with <code>###1###</code>, <code>###2###</code> markers, and when the abbreviation expands, it prompts you to fill in each placeholder interactively. The <code>###@###</code> marker tells it where to leave point after expansion. I wrote a <a href="https://www.rahuljuliato.com/posts/abbrev-mode">whole article about it</a>.</p><h3>Auth-Source</h3><p>Configures <code>auth-source</code> to use <code>~/.authinfo.gpg</code> for credential storage. Simple but essential if you use Gnus, ERC, or any network-facing Emacs feature.</p><h3>Auto-Revert</h3><p>Makes buffers automatically refresh when files change on disk. Essential for any Git workflow.</p><h3>Conf / Compilation</h3><p>Configuration file mode settings and a <code>compilation-mode</code> setup with ANSI color support, so compiler output actually looks readable.</p><h3>Window</h3><p>Custom window management beyond the defaults, because Emacs window management out of the box is <em>powerful</em> but needs a little nudging.</p><h3>Tab-Bar</h3><p>Tab-bar configuration for workspace management. Emacs has had tabs since version 27, and they're genuinely useful once you configure them properly.</p><h3>RCIRC and ERC</h3><p>Two IRC clients, both built into Emacs, both configured. ERC gets the bigger treatment: logging, scrolltobottom, fill, match highlighting, and even inline image support (via one of the extra modules). The Emacs 31 cycle brought nice improvements here too, including a fix for the scrolltobottom/fill-wrap dependency issue.</p><h3>Icomplete</h3><p>This is where Emacs Solo's completion story lives. Instead of reaching for Vertico, Consult, or Helm, I use <code>icomplete-vertical-mode</code>, which is built into Emacs. With the right settings it's surprisingly capable:</p><p>I've also been contributing patches upstream to improve icomplete's vertical rendering with prefix indicators. Some of those features are already landing in Emacs 31, which means the polyfill code I carry today will eventually become unnecessary.</p><h3>Dired</h3><p>A heavily customized Dired setup. Custom listing switches, human readable sizes, integration with system openers (<code>open</code> on macOS, <code>xdg-open</code> on Linux), and the <code>dired-hide-details-hide-absolute-location</code> option from Emacs 31.</p><h3>WDired</h3><p>Writable Dired, so you can rename files by editing the buffer directly.</p><h3>Eshell</h3><p>This one I'm particularly proud of. Emacs Solo's Eshell configuration includes:</p><p>— <strong>Shared history across all Eshell buffers</strong>: Every Eshell instance reads from and writes to a merged history, so you never lose a command just because you ran it in a different buffer</p><p>— <strong>Custom prompts</strong>: Multiple prompt styles you can toggle between with <code>C-c t</code> (full vs. minimal) and <code>C-c T</code> (lighter vs. heavier full prompt)</p><p>— A custom <strong>welcome banner</strong> with keybinding hints</p><p>— History size of 100,000 entries with deduplication</p><h3>Isearch</h3><p>Enhanced incremental search with sensible defaults.</p><h3>VC (Version Control)</h3><p>This is one of the largest sections and one I'm most invested in. Emacs's built-in <code>vc</code> is an incredible piece of software that most people overlook in favor of Magit. I'm not saying it replaces Magit entirely, but with the right configuration it covers 95% of daily Git operations:</p><p>— <strong>Git add/reset from vc-dir</strong>: <code>S</code> to stage, <code>U</code> to unstage, directly in the <code>vc-dir</code> buffer. Admittedly, I almost never use this because I'm now used to the Emacs-style VC workflow: <code>C-x v D</code> or <code>C-x v =</code>, then killing what I don’t want, splitting what isn’t ready yet, and finishing with <code>C-c C-c</code>. Amending with <code>C-c C-e</code> is awesome. Still useful once or twice a semester.</p><p>— <strong>Git reflog viewer</strong>: A custom <code>emacs-solo/vc-git-reflog</code> command with ANSI color rendering and navigation keybindings</p><p>— <strong>Browse remote</strong>: <code>C-x v B</code> opens your repository on GitHub/GitLab in a browser; with a prefix argument it jumps to the current file and line</p><p>— <strong>Jump to current hunk</strong>: <code>C-x v =</code> opens the diff buffer scrolled to the hunk containing your current line</p><p>— <strong>Switch between modified files</strong>: <code>C-x C-g</code> lets you <code>completing-read</code> through all modified/untracked files in the current repo</p><p>— <strong>Pull current branch</strong>: A dedicated command for <code>git pull origin &lt;current-branch&gt;</code></p><p>— Emacs 31 settings: <code>vc-auto-revert-mode</code>, <code>vc-allow-rewriting-published-history</code>, <code>vc-dir-hide-up-to-date-on-revert</code></p><h3>Smerge / Diff / Ediff</h3><p>Merge conflict resolution and diff viewing. Ediff configured to split windows sanely (side by side, not in a new frame).</p><h3>Eldoc</h3><p>Documentation at point, with <code>eldoc-help-at-pt</code> (Emacs 31) for showing docs automatically.</p><h3>Eglot</h3><p>The LSP client that ships with Emacs. Configured with:</p><p>— Auto-shutdown of unused servers</p><p>— No event buffer logging (for performance)</p><p>— Custom server programs, including <strong>rassumfrassum</strong> for multiplexing TypeScript + ESLint + Tailwind (I wrote <a href="https://www.rahuljuliato.com/posts/eglot-rass">a whole post about that</a>)</p><p>— Keybindings under <code>C-c l</code> for code actions, rename, format, and inlay hints</p><p>— Automatic enabling for all <code>prog-mode</code> buffers except <code>emacs-lisp-mode</code> and <code>lisp-mode</code></p><h3>Flymake / Flyspell / Whitespace</h3><p>Diagnostics, spell checking, and whitespace visualization. All built-in, all configured.</p><h3>Gnus</h3><p>The Emacs newsreader and email client. Configured for IMAP/SMTP usage.</p><h3>Man</h3><p>Manual page viewer settings.</p><h3>Minibuffer</h3><p>Fine-tuned minibuffer behavior, including <code>completion-eager-update</code> from Emacs 31 for faster feedback during completion.</p><h3>Newsticker</h3><p>RSS/Atom feed reader built into Emacs. Customized with some extras I build my self for dealing with youtube feeds: thumbnail, transcripts, sending to AI for a quick summary, and so on.</p><h3>Electric-Pair / Paren</h3><p>Auto-closing brackets and parenthesis highlighting.</p><h3>Proced</h3><p>Process manager (like <code>top</code>, but inside Emacs).</p><h3>Org</h3><p>Org-mode configuration, because of course.</p><h3>Speedbar</h3><p>File tree navigation in a side window. With Emacs 31, speedbar gained <code>speedbar-window</code> support, so it can live inside your existing frame instead of spawning a new one.</p><h3>Time</h3><p>World clock with multiple time zones, sorted by ISO timestamp (Emacs 31).</p><h3>Uniquify</h3><p>Buffer name disambiguation when you have multiple files with the same name open.</p><h3>Which-Key</h3><p>Key discovery. Built into Emacs since version 30.</p><h3>Webjump</h3><p>Quick web searches from the minibuffer. Configured with useful search engines.</p><h3>Language Modes</h3><p>Specific configurations for every language I work with, organized into three areas:</p><p><strong>Common Lisp</strong>: <code>inferior-lisp</code> and <code>lisp-mode</code> with custom REPL interaction, evaluation commands, and a poor man's SLIME/SLY setup that actually works quite well for basic Common Lisp development.</p><p><strong>Non-Tree-sitter</strong>: <code>sass-mode</code> for when tree-sitter grammars aren't available.</p><p><strong>Tree-sitter modes</strong>: <code>ruby-ts-mode</code>, <code>js-ts-mode</code>, <code>json-ts-mode</code>, <code>typescript-ts-mode</code>, <code>bash-ts-mode</code>, <code>rust-ts-mode</code>, <code>toml-ts-mode</code>, <code>markdown-ts-mode</code> (Emacs 31), <code>yaml-ts-mode</code>, <code>dockerfile-ts-mode</code>, <code>go-ts-mode</code>. Each one configured with tree-sitter grammar sources (which Emacs 31 is starting to define internally, so those definitions will eventually become unnecessary).</p><hr /><h2>The Extras: 35 Self-Contained Modules</h2><p>This is where the fun really is. Each of these is a complete, standalone Elisp file that reimplements functionality you'd normally get from an external package. They're all in <code>lisp/</code> and can be used independently.</p><p>I call them "hacky reimplementations" in the spirit of Emacs Solo: they're not trying to be feature-complete replacements for their MELPA counterparts. They're trying to be <strong>small, understandable, and good enough</strong> for daily use while keeping the config self-contained.</p><h3>emacs-solo-themes</h3><p><strong>Custom color themes based on Modus.</strong> Provides several theme variants: Catppuccin Mocha, Crafters (the default), Matrix, and GITS. All built on top of Emacs's built-in Modus themes by overriding faces, so you get the accessibility and completeness of Modus with different aesthetics.</p><h3>emacs-solo-mode-line</h3><p><strong>Custom mode-line format and configuration.</strong> A hand-crafted mode-line that shows exactly what I want: buffer state indicators, file name, major mode, Git branch, line/column, and nothing else. No <code>doom-modeline</code>, no <code>telephone-line</code>, just format strings and faces.</p><h3>emacs-solo-movements</h3><p><strong>Enhanced navigation and window movement commands.</strong> Extra commands for moving between windows, resizing splits, and navigating buffers more efficiently.</p><h3>emacs-solo-formatter</h3><p><strong>Configurable format-on-save with a formatter registry.</strong> You register formatters by file extension (e.g., <code>prettier</code> for <code>.tsx</code>, <code>black</code> for <code>.py</code>), and the module automatically hooks into <code>after-save-hook</code> to format the buffer. All controllable via a <code>defcustom</code>, so you can toggle it on and off globally.</p><h3>emacs-solo-transparency</h3><p><strong>Frame transparency for GUI and terminal.</strong> Toggle transparency on your Emacs frame. Works on both graphical and terminal Emacs, using the appropriate mechanism for each.</p><h3>emacs-solo-exec-path-from-shell</h3><p><strong>Sync shell PATH into Emacs.</strong> The classic macOS problem: GUI Emacs doesn't inherit your shell's <code>PATH</code>. This module solves it the same way <code>exec-path-from-shell</code> does, but in about 20 lines instead of a full package.</p><h3>emacs-solo-rainbow-delimiters</h3><p><strong>Rainbow coloring for matching delimiters.</strong> Colorizes nested parentheses, brackets, and braces in different colors so you can visually match nesting levels. Essential for any Lisp, and helpful everywhere else.</p><h3>emacs-solo-project-select</h3><p><strong>Interactive project finder and switcher.</strong> A <code>completing-read</code> interface for finding and switching between projects, building on Emacs's built-in <code>project.el</code>.</p><h3>emacs-solo-viper-extensions</h3><p><strong>Vim-like keybindings and text objects for Viper.</strong> If you use Emacs's built-in <code>viper-mode</code> (the Vim emulation layer), this extends it with text objects and additional Vim-like commands. No Evil needed.</p><h3>emacs-solo-highlight-keywords</h3><p><strong>Highlight TODO and similar keywords in comments.</strong> Makes <code>TODO</code>, <code>FIXME</code>, <code>HACK</code>, <code>NOTE</code>, and similar keywords stand out in source code comments with distinctive faces. A small thing that makes a big difference.</p><h3>emacs-solo-gutter</h3><p><strong>Git diff gutter indicators in buffers.</strong> Shows added, modified, and deleted line indicators in the margin, like <code>diff-hl</code> or <code>git-gutter</code>. Pure Elisp, using <code>vc-git</code> under the hood.</p><h3>emacs-solo-ace-window</h3><p><strong>Quick window switching with labels.</strong> When you have three or more windows, this overlays single-character labels on each window so you can jump to any one with a single keystroke. A minimal reimplementation of the popular <code>ace-window</code> package.</p><h3>emacs-solo-olivetti</h3><p><strong>Centered document layout mode.</strong> Centers your text in the window with wide margins, like <code>olivetti-mode</code>. Great for prose writing, Org documents, or any time you want a distraction-free centered layout.</p><h3>emacs-solo-0x0</h3><p><strong>Upload text and files to 0x0.st.</strong> Select a region or a file and upload it to the <a href="https://0x0.st">0x0.st</a> paste service. The URL is copied to your kill ring. Quick and useful for sharing snippets.</p><h3>emacs-solo-sudo-edit</h3><p><strong>Edit files as root via TRAMP.</strong> Reopen the current file with root privileges using TRAMP's <code>/sudo::</code> prefix. A reimplementation of the <code>sudo-edit</code> package.</p><h3>emacs-solo-replace-as-diff</h3><p><strong>Multi-file regexp replace with diff preview.</strong> Perform a search-and-replace across multiple files and see the changes as a diff before applying them. This one turned out to be more useful than I expected.</p><h3>emacs-solo-weather</h3><p><strong>Weather forecast from wttr.in.</strong> Fetches weather data from <a href="https://wttr.in">wttr.in</a> and displays it in an Emacs buffer. Because checking the weather shouldn't require leaving Emacs.</p><h3>emacs-solo-rate</h3><p><strong>Cryptocurrency and fiat exchange rate viewer.</strong> Query exchange rates and display them inside Emacs. For when you need to know how much a bitcoin is worth but refuse to open a browser tab.</p><h3>emacs-solo-how-in</h3><p><strong>Query cheat.sh for programming answers.</strong> Ask "how do I do X in language Y?" and get an answer from <a href="https://cheat.sh">cheat.sh</a> displayed right in Emacs. Like <code>howdoi</code> but simpler.</p><h3>emacs-solo-ai</h3><p><strong>AI assistant integration (Ollama, Gemini, Claude).</strong> Send prompts to AI models directly from Emacs. Supports multiple backends: local Ollama, Google Gemini, and Anthropic Claude. The response streams into a buffer. No <code>gptel</code>, no <code>ellama</code>, just <code>url-retrieve</code> and some JSON parsing.</p><h3>emacs-solo-dired-gutter</h3><p><strong>Git status indicators in Dired buffers.</strong> Shows Git status (modified, added, untracked) next to file names in Dired, using colored indicators in the margin. Think <code>diff-hl-dired-mode</code> but self-contained.</p><h3>emacs-solo-dired-mpv</h3><p><strong>Audio player for Dired using mpv.</strong> Mark audio files in Dired, hit <code>C-c m</code>, and play them through mpv. You get a persistent mpv session you can control from anywhere with <code>C-c m</code>. A mini music player that lives inside your file manager.</p><h3>emacs-solo-icons</h3><p><strong>File type icon definitions for Emacs Solo.</strong> The icon registry that maps file extensions and major modes to Unicode/Nerd Font icons. This is the foundation that the next three modules build on.</p><h3>emacs-solo-icons-dired</h3><p><strong>File type icons for Dired buffers.</strong> Displays file type icons next to file names in Dired. Uses Nerd Font glyphs.</p><h3>emacs-solo-icons-eshell</h3><p><strong>File type icons for Eshell listings.</strong> Same as above but for Eshell's <code>ls</code> output.</p><h3>emacs-solo-icons-ibuffer</h3><p><strong>File type icons for ibuffer.</strong> And again for the buffer list.</p><h3>emacs-solo-container</h3><p><strong>Container management UI for Docker and Podman.</strong> A full <code>tabulated-list-mode</code> interface for managing containers: list, start, stop, restart, remove, inspect, view logs, open a shell. Works with both Docker and Podman. This one started small and grew into a genuinely useful tool.</p><h3>emacs-solo-m3u</h3><p><strong>M3U playlist viewer and online radio player.</strong> Open <code>.m3u</code> playlist files, browse the entries, and play them with mpv. <code>RET</code> to play, <code>x</code> to stop. Great for online radio streams.</p><h3>emacs-solo-clipboard</h3><p><strong>System clipboard integration for terminals.</strong> Makes copy/paste work correctly between Emacs running in a terminal and the system clipboard. Solves the eternal terminal Emacs clipboard problem.</p><h3>emacs-solo-eldoc-box</h3><p><strong>Eldoc documentation in a child frame.</strong> Shows eldoc documentation in a floating child frame near point instead of the echo area. A reimplementation of the <code>eldoc-box</code> package.</p><h3>emacs-solo-khard</h3><p><strong>Khard contacts browser.</strong> Browse and search your <a href="https://github.com/lucc/khard">khard</a> address book from inside Emacs. Niche, but if you use khard for contact management, this is handy.</p><h3>emacs-solo-flymake-eslint</h3><p><strong>Flymake backend for ESLint.</strong> Runs ESLint as a Flymake checker for JavaScript/TypeScript files. Disabled by default now that LSP servers handle ESLint natively, but still available if you prefer the standalone approach.</p><h3>emacs-solo-erc-image</h3><p><strong>Inline images in ERC chat buffers.</strong> When someone posts an image URL in IRC, this fetches and displays the image inline in the ERC buffer. A small luxury that makes IRC feel more modern.</p><h3>emacs-solo-yt</h3><p><strong>YouTube search and playback with yt-dlp and mpv.</strong> Search YouTube from Emacs, browse results, and play videos (or just audio) through mpv. Because sometimes you need background music and YouTube is right there.</p><h3>emacs-solo-gh</h3><p><strong>GitHub CLI interface with transient menu.</strong> A transient-based menu for the <code>gh</code> CLI tool. Browse issues, pull requests, run actions, all from a structured Emacs interface without memorizing <code>gh</code> subcommands.</p><hr /><h2>Emacs 31: Looking Forward</h2><p>Throughout the config you'll see comments tagged <code>; EMACS-31</code> marking features that are coming (or already available on the development branch). Some highlights:</p><p>— <strong>Window layout commands</strong>: <code>window-layout-transpose</code>, <code>window-layout-rotate-clockwise</code>, and flip commands. Finally, first-class support for rearranging window layouts</p><p>— <strong>Tree-sitter grammar sources defined in modes</strong>: No more manually specifying <code>treesit-language-source-alist</code> entries for every language</p><p>— <strong><code>markdown-ts-mode</code></strong>: Tree-sitter powered Markdown, built-in</p><p>— <strong>Icomplete improvements</strong>: In-buffer adjustment, prefix indicators, and better vertical rendering</p><p>— <strong>Speedbar in-frame</strong>: <code>speedbar-window</code> lets the speedbar live inside your frame as a normal window</p><p>— <strong>VC enhancements</strong>: <code>vc-dir-hide-up-to-date-on-revert</code>, <code>vc-auto-revert-mode</code>, <code>vc-allow-rewriting-published-history</code></p><p>— <strong>ERC fixes</strong>: The scrolltobottom/fill-wrap dependency is finally resolved</p><p>— <strong><code>native-comp-async-on-battery-power</code></strong>: Don't waste battery on native compilation</p><p>— <strong><code>kill-region-dwim</code></strong>: Smart kill-region behavior</p><p>— <strong><code>delete-pair-push-mark</code></strong>: Better delete-pair with mark pushing</p><p>— <strong>World clock sorting</strong>: <code>world-clock-sort-order</code> for sensible timezone display</p><p>I tag these not just for my own reference, but so that anyone reading the config can see exactly which parts will become cleaner or unnecessary as Emacs 31 stabilizes. Some of the polyfill code I carry today, particularly around icomplete, exists specifically because those features haven't landed in a stable release yet.</p><hr /><h2>What I've Learned</h2><p>This latest cycle of working on Emacs Solo taught me a few things worth sharing.</p><p><strong>Emacs gives you more than you think.</strong> Every time I set out to "reimplement" something, I discovered that Emacs already had 70% of it built in. <code>vc</code> is far more capable than most people realize. <code>icomplete-vertical-mode</code> is genuinely good. <code>tab-bar-mode</code> is a real workspace manager. <code>proced</code> is a real process manager. The gap between "built-in Emacs" and "Emacs with 50 packages" is smaller than the community often assumes.</p><p><strong>Writing your own packages is the best way to learn Elisp.</strong> I learned more about Emacs Lisp writing <code>emacs-solo-gutter</code> and <code>emacs-solo-container</code> than I did in years of tweaking other people's configs. When you have to implement something from scratch, you're forced to understand <code>overlays</code>, <code>process filters</code>, <code>tabulated-list-mode</code>, <code>transient</code>, <code>child frames</code>, and all the machinery that packages usually hide from you.</p><p><strong>Small is beautiful.</strong> Most of the modules in <code>lisp/</code> are under 200 lines. Some are under 50. They don't try to handle every edge case. They handle <em>my</em> edge cases, and that's enough. If someone else needs something different, the code is simple enough to fork and modify.</p><p><strong>Contributing upstream is worth it.</strong> Some of the things I built as workarounds (like the icomplete vertical prefix indicators) turned into upstream patches. When you're deep enough in a feature to build a workaround, you're deep enough to propose a fix.</p><hr /><h2>Conclusion</h2><p>Emacs Solo started as a personal challenge: can I have a productive, modern Emacs setup without installing a single external package?</p><p>The answer, after this cycle, is a definitive <strong>yes</strong>.</p><p>Is it for everyone? Absolutely not. If you're happy with Doom Emacs or Spacemacs or your own carefully curated package list, that's great. Those are excellent choices.</p><p>But if you're curious about what Emacs can do on its own, if you want a config where you understand every line, if you want something you can hand to someone and say "just drop this into <code>~/.emacs.d/</code> and it works", then maybe Emacs Solo is worth a look.</p><p>The repository is here: <a href="https://github.com/LionyxML/emacs-solo">https://github.com/LionyxML/emacs-solo</a></p><p>It's been a lot of fun. I learned more in this cycle than in any previous one. And if anyone out there finds even a single module or config snippet useful, I'd be happy.</p><p>That's the whole point, really. Sharing what works.</p><hr /><h2>Acknowledgements</h2><p>None of this exists in a vacuum, and I want to give proper thanks.</p><p>First and foremost, to the <strong>Emacs core team</strong>. The people who maintain and develop GNU Emacs are doing extraordinary work, often quietly, often thanklessly. Every built-in feature I configure in <code>init.el</code> is the result of decades of careful engineering. The fact that Emacs 31 keeps making things <em>better</em> in ways that matter (tree-sitter integration, icomplete improvements, VC enhancements, window layout commands) is a testament to how alive this project is.</p><p>While working on Emacs Solo I also had the opportunity to contribute directly to Emacs itself. I originally wrote <code>markdown-ts-mode</code>, which was later improved and integrated with the help and review of Emacs maintainers. I also contributed changes such as aligning <code>icomplete</code> candidates with point in the buffer (similar to Corfu or Company) and a few fixes to <code>newsticker</code>.</p><p>I'm very grateful for the help, reviews, patience, and guidance from people like <strong>Eli Zaretskii</strong>, <strong>Yuan Fu</strong>, <strong>Stéphane Marks</strong>, <strong>João Távora</strong>, and others on the mailing lists.</p><p>To the <strong>authors of every package that inspired a module in <code>lisp/</code></strong>. Even though Emacs Solo doesn't install external packages, it is deeply influenced by them. <code>diff-hl</code>, <code>ace-window</code>, <code>olivetti</code>, <code>doom-modeline</code>, <code>exec-path-from-shell</code>, <code>eldoc-box</code>, <code>rainbow-delimiters</code>, <code>sudo-edit</code>, and many others showed me what was possible and set the bar for what a good Emacs experience looks like. Where specific credit is due, it's noted in the source code itself.</p><p>A special thanks to <strong>David Wilson (daviwil) and the System Crafters community</strong>. David's streams and videos were foundational for me in understanding how to build an Emacs config from scratch, and the System Crafters community has been an incredibly welcoming and knowledgeable group of people. The "Crafters" theme variant in Emacs Solo exists as a direct nod to that influence.</p><p>To <strong>Protesilaos Stavrou (Prot)</strong>, whose work on Modus themes, Denote, and his thoughtful writing about Emacs philosophy has shaped how I think about software defaults, accessibility, and keeping things simple. The fact that Emacs Solo's themes are built on top of Modus is no coincidence.</p><p>And to <strong>Gopar (goparism)</strong>, whose Emacs content and enthusiasm for exploring Emacs from the ground up resonated deeply with the spirit of this project. It's encouraging to see others who believe in understanding the tools we use.</p><p>To everyone who I probably forgot to mention, who has opened issues, suggested features, or just tried Emacs Solo and told me about it: thank you. Open source is a conversation, and every bit of feedback makes the project better.</p>]]></description>
      <link>https://www.rahuljuliato.com/posts/emacs-solo-two-years</link>
      <guid>https://www.rahuljuliato.com/posts/emacs-solo-two-years</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Opinion | A.I. Is Changing the Way We Think About Good and Evil - The New York Times]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.nytimes.com/2026/03/10/opinion/ai-chatbots-virtue-vice.html</link>
      <guid>https://www.nytimes.com/2026/03/10/opinion/ai-chatbots-virtue-vice.html</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[ZIP Code First]]></title>
      <description><![CDATA[ZIP Code First
<p>A US ZIP code is <strong>5 characters</strong>. From those 5 characters you can determine the city, the state, and the country. That's 3 fields. Autofilled. From one input.</p>
<p>But you don't do that, do you? No. You make me type my street address, then my city, then scroll through a dropdown of 50 states to find Illinois wedged between Idaho and Indiana, then type my ZIP, then — the pièce de résistance — scroll through <strong>200+ countries</strong> to find United States, which half the time is filed under "T" because some dipshit thought "The United States of America" was the correct sort key.</p>
<p>It's 2026. What the fuck are we doing.</p>
<h2>It's 5 keystrokes.</h2>
<p>I type <code>90210</code>. You now know I'm in <strong>Beverly Hills, California, United States</strong>. You didn't need me to tell you that. You didn't need a dropdown. You didn't need me to scroll past Turkmenistan. You had the answer the entire time, in 5 digits, and you just... didn't use it.</p>
<p>And here's the bonus: once you know the ZIP, your street address autocomplete is searching a few thousand addresses instead of <strong>160 million</strong>. It's faster. It's more accurate. I type less. You get cleaner data. Everyone wins.</p>
<p>This is not new technology. Free APIs exist. It's like 4 lines of code. Look:</p>
<pre>const res = await fetch(`https://api.zippopotam.us/us/${zip}`)
const data = await res.json()
city.value = data.places[0]["place name"]
state.value = data.places[0]["state"]
country.value = "United States"</pre>
<p>That's it. That's the whole thing. You could have shipped this instead of reading this website.</p>
<h2>Don't believe me? Try it.</h2>
<p><label>ZIP Code</label> <label>City</label> <label>State</label> <label>Country</label> <label>Street Address</label> </p>
<p>See how that works? See how you typed 5 numbers and 3 fields filled themselves in? See how you're now typing your street address and it already knows what city you're in? That's not magic. That's a lookup table. We've had those since the 1960s.</p>
<h2>The hall of shame.</h2>
<p><strong>Tier 1: ZIP at the bottom.</strong> Street, city, state, ZIP, country. You had the data to autofill 3 fields and you just... put it last. Amazon does this. Target does this. Walmart does this. Basically everyone does this. Billions of collective hours of human life, spent scrolling for "Illinois."</p>
<p><strong>Tier 2: No autofill at all.</strong> You collect the ZIP. You have the ZIP. You do nothing with it. The ZIP just sits there in your database, inert, like a fire extinguisher in a glass case that says "do not break." What are you saving it for.</p>
<p><strong>Tier 3: The scrollable country dropdown.</strong> 240 countries. No search. No type-ahead. Just pure, unfiltered, alphabetical scrolling. Bonus points if the US is under "T." Extra bonus points if it's not even alphabetical. You absolute psychopaths.</p>
<p><strong>Tier 4: The form that resets when you hit back.</strong> I filled out 14 fields. Your payment processor failed. I hit back. Everything is gone. My street. My city. My state. My will to live. All of it. Returned to the void. The developer responsible for this sleeps eight hours a night. That's the part that haunts me.</p>
<h2>Some other thoughts.</h2>
<p>While we're here:</p>
<p><strong>Invoke the right keyboard.</strong> If you're asking for a ZIP code, use <code>inputmode="numeric"</code>. It's one HTML attribute. On mobile, I should see a number pad, not a full QWERTY keyboard. This applies to phone numbers, credit cards, and anything else that's obviously just digits. You already know the input type. Tell the phone.</p>
<p><strong>Work with autofill, not against it.</strong> Browsers have had autofill for over a decade. Use the right <code>autocomplete</code> attributes — <code>postal-code</code>, <code>address-line1</code>, <code>country</code>. If your form fights the browser's autofill, your form is wrong. The browser is trying to save your user 45 seconds. Let it.</p>
<p><strong>Fine, maybe country first.</strong> The purists in the comments are technically correct — postal codes aren't globally unique. You could do country first (pre-filled via IP), then postal code, then let the magic happen. The point was never "skip the country field." The point is: <strong>stop making me type things you already know.</strong></p>
<h2>Submit to the wall of shame.</h2>
<div class="shame-box"><p>Found a site that puts the ZIP code last? A country dropdown sorted by vibes? A form that makes you cry?</p><p><a href="mailto:shame@zipcodefirst.com?subject=Wall%20of%20Shame%20Submission">Send it to us →</a></p><p class="c1"> Public wall of shame coming soon. </p></div>
<h2>So fix your forms.</h2>
<p>Put the ZIP code first. Autofill the city. Autofill the state. Autofill the country. Let the user type their street address last, with autocomplete scoped to their ZIP.</p>
<p>It is a solved problem. The API is free. The code is 5 lines. There is genuinely no reason not to do this other than the mass institutional inertia of a million product managers copy-pasting the same address form template from 2009 and never once asking "wait, why is the ZIP code at the bottom?"</p>
<p>Why <em>is</em> the ZIP code at the bottom?</p>
<p>Put it first, you animals.</p>
<p class="c2"><a href="https://twitter.com/intent/tweet?text=It%27s%202026.%20Put%20the%20ZIP%20code%20first.%20This%20isn%27t%20hard.&amp;url=https%3A%2F%2Fzipcodefirst.com" target="_blank">Tweet this</a> · <a href="https://news.ycombinator.com/submitlink?u=https%3A%2F%2Fzipcodefirst.com&amp;t=Put%20the%20ZIP%20code%20first" target="_blank">Post to HN</a> · <a href="#" id="copy-link">Copy link</a><br />Share this before you have to fill out another address form.</p>]]></description>
      <link>https://zipcodefirst.com/</link>
      <guid>https://zipcodefirst.com/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[karpathy/autoresearch: AI agents running research on single-GPU nanochat training automatically]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 class="heading-element" dir="auto">autoresearch</h1><a id="user-content-autoresearch" class="anchor" aria-label="Permalink: autoresearch" href="#autoresearch"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="progress.png"><img src="progress.png" alt="teaser" style="max-width: 100%;"></a></p>
<p dir="auto"><em>One day, frontier AI research used to be done by meat computers in between eating, sleeping, having other fun, and synchronizing once in a while using sound wave interconnect in the ritual of "group meeting". That era is long gone. Research is now entirely the domain of autonomous swarms of AI agents running across compute cluster megastructures in the skies. The agents claim that we are now in the 10,205th generation of the code base, in any case no one could tell if that's right or wrong as the "code" is now a self-modifying binary that has grown beyond human comprehension. This repo is the story of how it all began. -@karpathy, March 2026</em>.</p>
<p dir="auto">The idea: give an AI agent a small but real LLM training setup and let it experiment autonomously overnight. It modifies the code, trains for 5 minutes, checks if the result improved, keeps or discards, and repeats. You wake up in the morning to a log of experiments and (hopefully) a better model. The training code here is a simplified single-GPU implementation of <a href="https://github.com/karpathy/nanochat">nanochat</a>. The core idea is that you're not touching any of the Python files like you normally would as a researcher. Instead, you are programming the <code>program.md</code> Markdown files that provide context to the AI agents and set up your autonomous research org. The default <code>program.md</code> in this repo is intentionally kept as a bare bones baseline, though it's obvious how one would iterate on it over time to find the "research org code" that achieves the fastest research progress, how you'd add more agents to the mix, etc. A bit more context on this project is here in this <a href="https://x.com/karpathy/status/2029701092347630069" rel="nofollow">tweet</a>.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">How it works</h2><a id="user-content-how-it-works" class="anchor" aria-label="Permalink: How it works" href="#how-it-works"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The repo is deliberately kept small and only really has three files that matter:</p>
<ul dir="auto">
<li><strong><code>prepare.py</code></strong> — fixed constants, one-time data prep (downloads training data, trains a BPE tokenizer), and runtime utilities (dataloader, evaluation). Not modified.</li>
<li><strong><code>train.py</code></strong> — the single file the agent edits. Contains the full GPT model, optimizer (Muon + AdamW), and training loop. Everything is fair game: architecture, hyperparameters, optimizer, batch size, etc. <strong>This file is edited and iterated on by the agent</strong>.</li>
<li><strong><code>program.md</code></strong> — baseline instructions for one agent. Point your agent here and let it go. <strong>This file is edited and iterated on by the human</strong>.</li>
</ul>
<p dir="auto">By design, training runs for a <strong>fixed 5-minute time budget</strong> (wall clock, excluding startup/compilation), regardless of the details of your compute. The metric is <strong>val_bpb</strong> (validation bits per byte) — lower is better, and vocab-size-independent so architectural changes are fairly compared.</p>
<p dir="auto">If you are new to neural networks, this <a href="https://x.com/hooeem/status/2030720614752039185" rel="nofollow">"Dummy's Guide"</a> looks pretty good for a lot more context.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Quick start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>Requirements:</strong> A single NVIDIA GPU (tested on H100), Python 3.10+, <a href="https://docs.astral.sh/uv/" rel="nofollow">uv</a>.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
# 1. Install uv project manager (if you don't already have it)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. Install dependencies
uv sync

# 3. Download data and train tokenizer (one-time, ~2 min)
uv run prepare.py

# 4. Manually run a single training experiment (~5 min)
uv run train.py"><pre><span class="pl-c"><span class="pl-c">#</span> 1. Install uv project manager (if you don't already have it)</span>
curl -LsSf https://astral.sh/uv/install.sh <span class="pl-k">|</span> sh

<span class="pl-c"><span class="pl-c">#</span> 2. Install dependencies</span>
uv sync

<span class="pl-c"><span class="pl-c">#</span> 3. Download data and train tokenizer (one-time, ~2 min)</span>
uv run prepare.py

<span class="pl-c"><span class="pl-c">#</span> 4. Manually run a single training experiment (~5 min)</span>
uv run train.py</pre></div>
<p dir="auto">If the above commands all work ok, your setup is working and you can go into autonomous research mode.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Running the agent</h2><a id="user-content-running-the-agent" class="anchor" aria-label="Permalink: Running the agent" href="#running-the-agent"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Simply spin up your Claude/Codex or whatever you want in this repo (and disable all permissions), then you can prompt something like:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Hi have a look at program.md and let's kick off a new experiment! let's do the setup first."><pre class="notranslate"><code>Hi have a look at program.md and let's kick off a new experiment! let's do the setup first.
</code></pre></div>
<p dir="auto">The <code>program.md</code> file is essentially a super lightweight "skill".</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Project structure</h2><a id="user-content-project-structure" class="anchor" aria-label="Permalink: Project structure" href="#project-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="prepare.py      — constants, data prep + runtime utilities (do not modify)
train.py        — model, optimizer, training loop (agent modifies this)
program.md      — agent instructions
pyproject.toml  — dependencies"><pre class="notranslate"><code>prepare.py      — constants, data prep + runtime utilities (do not modify)
train.py        — model, optimizer, training loop (agent modifies this)
program.md      — agent instructions
pyproject.toml  — dependencies
</code></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Design choices</h2><a id="user-content-design-choices" class="anchor" aria-label="Permalink: Design choices" href="#design-choices"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Single file to modify.</strong> The agent only touches <code>train.py</code>. This keeps the scope manageable and diffs reviewable.</li>
<li><strong>Fixed time budget.</strong> Training always runs for exactly 5 minutes, regardless of your specific platform. This means you can expect approx 12 experiments/hour and approx 100 experiments while you sleep. There are two upsides of this design decision. First, this makes experiments directly comparable regardless of what the agent changes (model size, batch size, architecture, etc). Second, this means that autoresearch will find the most optimal model for your platform in that time budget. The downside is that your runs (and results) become not comparable to other people running on other compute platforms.</li>
<li><strong>Self-contained.</strong> No external dependencies beyond PyTorch and a few small packages. No distributed training, no complex configs. One GPU, one file, one metric.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Platform support</h2><a id="user-content-platform-support" class="anchor" aria-label="Permalink: Platform support" href="#platform-support"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This code currently requires that you have a single NVIDIA GPU. In principle it is quite possible to support CPU, MPS and other platforms but this would also bloat the code. I'm not 100% sure that I want to take this on personally right now. People can reference (or have their agents reference) the full/parent nanochat repository that has wider platform support and shows the various solutions (e.g. a Flash Attention 3 kernels fallback implementation, generic device support, autodetection, etc.), feel free to create forks or discussions for other platforms and I'm happy to link to them here in the README in some new notable forks section or etc.</p>
<p dir="auto">Seeing as there seems to be a lot of interest in tinkering with autoresearch on much smaller compute platforms than an H100, a few extra words. If you're going to try running autoresearch on smaller computers (Macbooks etc.), I'd recommend one of the forks below. On top of this, here are some recommendations for how to tune the defaults for much smaller models for aspiring forks:</p>
<ol dir="auto">
<li>To get half-decent results I'd use a dataset with a lot less entropy, e.g. this <a href="https://huggingface.co/datasets/karpathy/tinystories-gpt4-clean" rel="nofollow">TinyStories dataset</a>. These are GPT-4 generated short stories. Because the data is a lot narrower in scope, you will see reasonable results with a lot smaller models (if you try to sample from them after training).</li>
<li>You might experiment with decreasing <code>vocab_size</code>, e.g. from 8192 down to 4096, 2048, 1024, or even - simply byte-level tokenizer with 256 possibly bytes after utf-8 encoding.</li>
<li>In <code>prepare.py</code>, you'll want to lower <code>MAX_SEQ_LEN</code> a lot, depending on the computer even down to 256 etc. As you lower <code>MAX_SEQ_LEN</code>, you may want to experiment with increasing <code>DEVICE_BATCH_SIZE</code> in <code>train.py</code> slightly to compensate. The number of tokens per fwd/bwd pass is the product of these two.</li>
<li>Also in <code>prepare.py</code>, you'll want to decrease <code>EVAL_TOKENS</code> so that your validation loss is evaluated on a lot less data.</li>
<li>In <code>train.py</code>, the primary single knob that controls model complexity is the <code>DEPTH</code> (default 8, here). A lot of variables are just functions of this, so e.g. lower it down to e.g. 4.</li>
<li>You'll want to most likely use <code>WINDOW_PATTERN</code> of just "L", because "SSSL" uses alternating banded attention pattern that may be very inefficient for you. Try it.</li>
<li>You'll want to lower <code>TOTAL_BATCH_SIZE</code> a lot, but keep it powers of 2, e.g. down to <code>2**14</code> (~16K) or so even, hard to tell.</li>
</ol>
<p dir="auto">I think these would be the reasonable hyperparameters to play with. Ask your favorite coding agent for help and copy paste them this guide, as well as the full source code.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Notable forks</h2><a id="user-content-notable-forks" class="anchor" aria-label="Permalink: Notable forks" href="#notable-forks"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="https://github.com/miolini/autoresearch-macos">miolini/autoresearch-macos</a> (MacOS)</li>
<li><a href="https://github.com/trevin-creator/autoresearch-mlx">trevin-creator/autoresearch-mlx</a> (MacOS)</li>
<li><a href="https://github.com/jsegov/autoresearch-win-rtx">jsegov/autoresearch-win-rtx</a> (Windows)</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">MIT</p>
</article></div>]]></description>
      <link>https://github.com/karpathy/autoresearch</link>
      <guid>https://github.com/karpathy/autoresearch</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[tropes.md - Tropes AI tools overuse when writing]]></title>
      <description><![CDATA[<div class="space-y-4"><p class="text-sm text-muted leading-relaxed max-w-lg">A single file containing all cataloged AI writing tropes. Add it to your AI's system prompt to help it avoid these patterns (let's play cat and mouse!).</p><p class="text-xs text-muted leading-relaxed max-w-lg italic">Disclaimer: Creation of this file was AI-assisted. If you thought I was going to write out a .md file for AI myself you must be mad. AI for AI. Human for Human.</p><p><a href="denied:data:text/markdown;charset=utf-8,%23%20AI%20Writing%20Tropes%20to%20Avoid%0A%0AAdd%20this%20file%20to%20your%20AI%20assistant's%20system%20prompt%20or%20context%20to%20help%20it%20avoid%0Acommon%20AI%20writing%20patterns.%20Source%3A%20%5Btropes.fyi%5D(https%3A%2F%2Ftropes.fyi)%20by%20%5Bossama.is%5D(https%3A%2F%2Fossama.is)%0A%0A---%0A%0A%23%23%20Word%20Choice%0A%0A%23%23%23%20%22Quietly%22%20and%20Other%20Magic%20Adverbs%0A%0AOveruse%20of%20%22quietly%22%20and%20similar%20adverbs%20to%20convey%20subtle%20importance%20or%20understated%20power.%20AI%20reaches%20for%20these%20adverbs%20to%20make%20mundane%20descriptions%20feel%20significant.%20Also%20includes%3A%20%22deeply%22%2C%20%22fundamentally%22%2C%20%22remarkably%22%2C%20%22arguably%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22quietly%20orchestrating%20workflows%2C%20decisions%2C%20and%20interactions%22%0A-%20%22the%20one%20that%20quietly%20suffocates%20everything%20else%22%0A-%20%22a%20quiet%20intelligence%20behind%20it%22%0A%0A%23%23%23%20%22Delve%22%20and%20Friends%0A%0AUsed%20to%20be%20the%20most%20infamous%20AI%20tell.%20%22Delve%22%20went%20from%20an%20uncommon%20English%20word%20to%20appearing%20in%20a%20staggering%20percentage%20of%20AI-generated%20text.%20Part%20of%20a%20family%20of%20overused%20AI%20vocabulary%20including%20%22certainly%22%2C%20%22utilize%22%2C%20%22leverage%22%20(as%20a%20verb)%2C%20%22robust%22%2C%20%22streamline%22%2C%20and%20%22harness%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Let's%20delve%20into%20the%20details...%22%0A-%20%22Delving%20deeper%20into%20this%20topic...%22%0A-%20%22We%20certainly%20need%20to%20leverage%20these%20robust%20frameworks...%22%0A%0A%23%23%23%20%22Tapestry%22%20and%20%22Landscape%22%0A%0AOveruse%20of%20ornate%20or%20grandiose%20nouns%20where%20simpler%20words%20would%20do.%20%22Tapestry%22%20is%20used%20to%20describe%20anything%20interconnected.%20%22Landscape%22%20is%20used%20to%20describe%20any%20field%20or%20domain.%20Other%20offenders%3A%20%22paradigm%22%2C%20%22synergy%22%2C%20%22ecosystem%22%2C%20%22framework%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20rich%20tapestry%20of%20human%20experience...%22%0A-%20%22Navigating%20the%20complex%20landscape%20of%20modern%20AI...%22%0A-%20%22The%20ever-evolving%20landscape%20of%20technology...%22%0A%0A%23%23%23%20The%20%22Serves%20As%22%20Dodge%0A%0AReplacing%20simple%20%22is%22%20or%20%22are%22%20with%20pompous%20alternatives%20like%20%22serves%20as%22%2C%20%22stands%20as%22%2C%20%22marks%22%2C%20or%20%22represents%22.%20AI%20avoids%20basic%20copulas%20because%20its%20repetition%20penalty%20pushes%20it%20toward%20fancier%20constructions%20(I've%20studied%20this!).%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20building%20serves%20as%20a%20reminder%20of%20the%20city's%20heritage.%22%0A-%20%22Gallery%20825%20serves%20as%20LAAA's%20exhibition%20space%20for%20contemporary%20art.%22%0A-%20%22The%20station%20marks%20a%20pivotal%20moment%20in%20the%20evolution%20of%20regional%20transit.%22%0A%0A---%0A%0A%23%23%20Sentence%20Structure%0A%0A%23%23%23%20Negative%20Parallelism%0A%0AThe%20%22It's%20not%20X%20--%20it's%20Y%22%20pattern%2C%20often%20with%20an%20em%20dash.%20The%20single%20most%20commonly%20identified%20AI%20writing%20tell.%20Man%20I%20f*cking%20hate%20it.%20AI%20uses%20this%20to%20create%20false%20profundity%20by%20framing%20everything%20as%20a%20surprising%20reframe.%20One%20in%20a%20piece%20can%20be%20effective%3B%20ten%20in%20a%20blog%20post%20is%20a%20genuine%20insult%20to%20the%20reader.%20Before%20LLMs%2C%20people%20simply%20did%20not%20write%20like%20this%20at%20scale.%20Includes%20the%20causal%20variant%20%22not%20because%20X%2C%20but%20because%20Y%22%20where%20every%20explanation%20is%20framed%20as%20a%20surprise%20reveal.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22It's%20not%20bold.%20It's%20backwards.%22%0A-%20%22Feeding%20isn't%20nutrition.%20It's%20dialysis.%22%0A-%20%22Half%20the%20bugs%20you%20chase%20aren't%20in%20your%20code.%20They're%20in%20your%20head.%22%0A%0A%23%23%23%20%22Not%20X.%20Not%20Y.%20Just%20Z.%22%0A%0AThe%20dramatic%20countdown%20pattern.%20AI%20builds%20tension%20by%20negating%20two%20or%20more%20things%20before%20revealing%20the%20actual%20point.%20Creates%20a%20false%20sense%20of%20narrowing%20down%20to%20the%20truth.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Not%20a%20bug.%20Not%20a%20feature.%20A%20fundamental%20design%20flaw.%22%0A-%20%22Not%20ten.%20Not%20fifty.%20Five%20hundred%20and%20twenty-three%20lint%20violations%20across%2067%20files.%22%0A-%20%22not%20recklessly%2C%20not%20completely%2C%20but%20enough%22%0A%0A%23%23%23%20%22The%20X%3F%20A%20Y.%22%0A%0ASelf-posed%20rhetorical%20questions%20answered%20immediately%20in%20the%20next%20sentence%20or%20clause.%20The%20model%20asks%20a%20question%20nobody%20was%20asking%2C%20then%20answers%20it%20for%20dramatic%20effect.%20Thinks%20this%20is%20the%20epitome%20of%20great%20writing.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20result%3F%20Devastating.%22%0A-%20%22The%20worst%20part%3F%20Nobody%20saw%20it%20coming.%22%0A-%20%22The%20scary%20part%3F%20This%20attack%20vector%20is%20perfect%20for%20developers.%22%0A%0A%23%23%23%20Anaphora%20Abuse%0A%0ARepeating%20the%20same%20sentence%20opening%20multiple%20times%20in%20quick%20succession.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22They%20assume%20that%20users%20will%20pay...%20They%20assume%20that%20developers%20will%20build...%20They%20assume%20that%20ecosystems%20will%20emerge...%20They%20assume%20that...%22%0A-%20%22They%20could%20expose...%20They%20could%20offer...%20They%20could%20provide...%20They%20could%20create...%20They%20could%20let...%20They%20could%20unlock...%22%0A-%20%22They%20have%20built%20engines%2C%20but%20not%20vehicles.%20They%20have%20built%20power%2C%20but%20not%20leverage.%20They%20have%20built%20walls%2C%20but%20not%20doors.%22%0A%0A%23%23%23%20Tricolon%20Abuse%0A%0AOveruse%20of%20the%20rule-of-three%20pattern%2C%20often%20extended%20to%20four%20or%20five.%20A%20single%20tricolon%20is%20elegant%3B%20three%20back-to-back%20tricolons%20are%20a%20pattern%20recognition%20failure.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Products%20impress%20people%3B%20platforms%20empower%20them.%20Products%20solve%20problems%3B%20platforms%20create%20worlds.%20Products%20scale%20linearly%3B%20platforms%20scale%20exponentially.%22%0A-%20%22identity%2C%20payments%2C%20compute%2C%20distribution%22%0A-%20%22workflows%2C%20decisions%2C%20and%20interactions%22%0A%0A%23%23%23%20%22It's%20Worth%20Noting%22%0A%0AFiller%20transitions%20that%20signal%20nothing.%20AI%20uses%20these%20phrases%20to%20introduce%20new%20points%20without%20actually%20connecting%20them%20to%20the%20previous%20argument.%20Also%20includes%3A%20%22It%20bears%20mentioning%22%2C%20%22Importantly%22%2C%20%22Interestingly%22%2C%20%22Notably%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22It's%20worth%20noting%20that%20this%20approach%20has%20limitations.%22%0A-%20%22Importantly%2C%20we%20must%20consider%20the%20broader%20implications.%22%0A-%20%22Interestingly%2C%20this%20pattern%20repeats%20across%20industries.%22%0A%0A%23%23%23%20Superficial%20Analyses%0A%0ATacking%20a%20present%20participle%20(%22-ing%22)%20phrase%20onto%20the%20end%20of%20a%20sentence%20to%20inject%20shallow%20analysis%20that%20says%20nothing.%20The%20model%20attaches%20significance%2C%20legacy%2C%20or%20broader%20meaning%20to%20mundane%20facts%20using%20phrases%20like%20%22highlighting%20its%20importance%22%2C%20%22reflecting%20broader%20trends%22%2C%20or%20%22contributing%20to%20the%20development%20of...%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22contributing%20to%20the%20region's%20rich%20cultural%20heritage%22%0A-%20%22This%20etymology%20highlights%20the%20enduring%20legacy%20of%20the%20community's%20resistance%20and%20the%20transformative%20power%20of%20unity%20in%20shaping%20its%20identity.%22%0A-%20%22underscoring%20its%20role%20as%20a%20dynamic%20hub%20of%20activity%20and%20culture%22%0A%0A%23%23%23%20False%20Ranges%0A%0AUsing%20%22from%20X%20to%20Y%22%20constructions%20where%20X%20and%20Y%20aren't%20on%20any%20real%20scale.%20In%20legitimate%20use%2C%20%22from%20X%20to%20Y%22%20implies%20a%20spectrum%20with%20a%20meaningful%20middle.%20AI%20uses%20it%20as%20a%20fancy%20way%20to%20list%20two%20loosely%20related%20things.%20%22From%20innovation%20to%20cultural%20transformation%22%20--%20what's%20in%20between%3F%3F%3F%3F%20Nothing!%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22From%20innovation%20to%20implementation%20to%20cultural%20transformation.%22%0A-%20%22From%20the%20singularity%20of%20the%20Big%20Bang%20to%20the%20grand%20cosmic%20web.%22%0A-%20%22From%20problem-solving%20and%20tool-making%20to%20scientific%20discovery%2C%20artistic%20expression%2C%20and%20technological%20innovation.%22%0A%0A%23%23%23%20Gerund%20Fragment%20Litany%0A%0AAfter%20making%20a%20claim%2C%20AI%20illustrates%20it%20with%20a%20stream%20of%20verbless%20gerund%20fragments%20%E2%80%94%20standalone%20sentences%20with%20no%20grammatical%20subject.%20%22Fixing%20small%20bugs.%20Writing%20straightforward%20features.%20Implementing%20well-defined%20tickets.%22%20The%20first%20sentence%20already%20said%20everything.%20The%20fragments%20add%20nothing%20except%20word%20count%20and%20that%20familiar%20AI%20cadence.%20Humans%20don't%20write%20first%20drafts%20this%20way.%20It's%20a%20pure%20structural%20tic.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Fixing%20small%20bugs.%20Writing%20straightforward%20features.%20Implementing%20well-defined%20tickets.%22%0A-%20%22Reviewing%20pull%20requests.%20Debugging%20edge%20cases.%20Attending%20architecture%20meetings.%22%0A-%20%22Shipping%20faster.%20Moving%20quicker.%20Delivering%20more.%22%0A%0A---%0A%0A%23%23%20Paragraph%20Structure%0A%0A%23%23%23%20Short%20Punchy%20Fragments%0A%0AExcessive%20use%20of%20very%20short%20sentences%20or%20sentence%20fragments%20as%20standalone%20paragraphs%20for%20manufactured%20emphasis.%20RLHF%20training%20has%20pushed%20models%20toward%20%22writing%20for%20readability%22%20aimed%20at%20the%20lowest%20common%20denominator%3A%20one%20thought%20per%20sentence%2C%20no%20mental%20state-keeping%20required.%20It's%20an%20inhuman%20style.%20No%20real%20person%20writes%20first%20drafts%20this%20way%20because%20it%20doesn't%20match%20how%20humans%20think%20or%20speak.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22He%20published%20this.%20Openly.%20In%20a%20book.%20As%20a%20priest.%22%0A-%20%22These%20weren't%20just%20products.%20And%20the%20software%20side%20matched.%20Then%20it%20professionalised.%20But%20I%20adapted.%22%0A-%20%22Platforms%20do.%22%0A%0A%23%23%23%20Listicle%20in%20a%20Trench%20Coat%0A%0ANumbered%20or%20labeled%20points%20dressed%20up%20as%20continuous%20prose.%20The%20model%20writes%20what%20is%20essentially%20a%20listicle%20but%20wraps%20each%20point%20in%20a%20paragraph%20that%20starts%20with%20%22The%20first...%20The%20second...%20The%20third...%22%20to%20disguise%20the%20format.%20Perhaps%20you%20told%20it%20to%20stop%20generating%20lists%20and%20it%20decided%20to%20do%20this%20instead...%20still%20very%20common.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20first%20wall%20is%20the%20absence%20of%20a%20free%2C%20scoped%20API...%20The%20second%20wall%20is%20the%20lack%20of%20delegated%20access...%20The%20third%20wall%20is%20the%20absence%20of%20scoped%20permissions...%22%0A-%20%22The%20second%20takeaway%20is%20that...%20The%20third%20takeaway%20is%20that...%20The%20fourth%20takeaway%20is%20that...%22%0A%0A---%0A%0A%23%23%20Tone%0A%0A%23%23%23%20%22Here's%20the%20Kicker%22%0A%0AFalse%20suspense%20transitions%20that%20promise%20a%20revelation%20but%20deliver%20a%20point%20that%20did%20NOT%20need%20the%20buildup.%20The%20model%20uses%20these%20phrases%20to%20manufacture%20drama%20before%20an%20otherwise%20unremarkable%20observation%20LOL.%20Also%20includes%3A%20%22Here's%20the%20thing%22%2C%20%22Here's%20where%20it%20gets%20interesting%22%2C%20%22Here's%20what%20most%20people%20miss%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Here's%20the%20kicker.%22%0A-%20%22Here's%20the%20thing%20about%20AI%20adoption.%22%0A-%20%22Here's%20where%20it%20gets%20interesting.%22%0A%0A%23%23%23%20%22Think%20of%20It%20As...%22%0A%0AThe%20patronizing%20analogy.%20AI%20constantly%20reaches%20for%20%22Think%20of%20it%20as...%22%20or%20%22It's%20like%20a...%22%20to%20simplify%20concepts.%20The%20model%20defaults%20to%20teacher%20mode%20and%20assumes%20the%20reader%20needs%20a%20metaphor%20to%20understand%20anything.%20Often%20produces%20analogies%20that%20are%20less%20clear%20than%20the%20original%20concept.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Think%20of%20it%20like%20a%20highway%20system%20for%20data.%22%0A-%20%22Think%20of%20it%20as%20a%20Swiss%20Army%20knife%20for%20your%20workflow.%22%0A-%20%22It's%20like%20asking%20someone%20to%20buy%20a%20car%20they're%20only%20allowed%20to%20sit%20in%20while%20it's%20parked.%22%0A%0A%23%23%23%20%22Imagine%20a%20World%20Where...%22%0A%0AThe%20classic%20AI%20invitation%20to%20futurism.%20To%20sell%20the%20argument%20usually%20begins%20with%20%22Imagine%22%20followed%20by%20a%20list%20of%20wonderful%20things%20that%20will%20happen%20if%20the%20reader%20agrees%20with%20the%20premise.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Imagine%20a%20world%20where%20every%20tool%20you%20use%20--%20your%20calendar%2C%20your%20inbox%2C%20your%20documents%2C%20your%20CRM%2C%20your%20code%20editor%20--%20has%20a%20quiet%20intelligence%20behind%20it...%22%0A-%20%22In%20that%20world%2C%20workflows%20stop%20being%20collections%20of%20manual%20steps%20and%20start%20becoming%20orchestrations.%22%0A%0A%23%23%23%20False%20Vulnerability%0A%0ASimulated%20self-awareness%20or%20honesty%20that%20reads%20as%20performative.%20The%20model%20pretends%20to%20break%20the%20fourth%20wall%20or%20admit%20a%20bias%2C%20creating%20a%20false%20sense%20of%20authenticity.%20Real%20vulnerability%20is%20specific%20and%20uncomfortable%3B%20AI%20vulnerability%20is%20polished%20and%20risk-free!!!!%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22And%20yes%2C%20I'm%20openly%20in%20love%20with%20the%20platform%20model%22%0A-%20%22And%20yes%2C%20since%20we're%20being%20honest%3A%20I'm%20looking%20at%20you%2C%20OpenAI%2C%20Google%2C%20Anthropic%2C%20Meta%22%0A-%20%22This%20is%20not%20a%20rant%3B%20it's%20a%20diagnosis%22%0A%0A%23%23%23%20%22The%20Truth%20Is%20Simple%22%0A%0AAsserting%20that%20something%20is%20obvious%2C%20clear%20or%20simple%20instead%20of%20actually%20proving%20it.%20If%20you%20have%20to%20tell%20the%20reader%20your%20point%20is%20clear%2C%20it%20very%20likely%20isn't.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20reality%20is%20simpler%20and%20less%20flattering%22%0A-%20%22History%20is%20unambiguous%20on%20this%20point%22%0A-%20%22History%20is%20clear%2C%20the%20metrics%20are%20clear%2C%20the%20examples%20are%20clear%22%0A%0A%23%23%23%20Grandiose%20Stakes%20Inflation%0A%0AEverything%20is%20the%20most%20important%20thing%20ever.%20AI%20inflates%20the%20stakes%20of%20every%20argument%20to%20world-historical%20significance.%20A%20blog%20post%20about%20API%20pricing%20becomes%20a%20meditation%20on%20the%20fate%20of%20civilization.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22This%20will%20fundamentally%20reshape%20how%20we%20think%20about%20everything.%22%0A-%20%22will%20define%20the%20next%20era%20of%20computing%22%0A-%20%22something%20entirely%20new%22%0A%0A%23%23%23%20%22Let's%20Break%20This%20Down%22%0A%0AThe%20pedagogical%20voice%20that%20assumes%20the%20reader%20needs%20hand-holding.%20AI%20defaults%20to%20a%20teacher-student%20dynamic%20even%20when%20writing%20for%20expert%20audiences.%20Also%20includes%3A%20%22Let's%20unpack%20this%22%2C%20%22Let's%20explore%22%2C%20%22Let's%20dive%20in%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Let's%20break%20this%20down%20step%20by%20step.%22%0A-%20%22Let's%20unpack%20what%20this%20really%20means.%22%0A-%20%22Let's%20explore%20this%20idea%20further.%22%0A%0A%23%23%23%20Vague%20Attributions%0A%0AAttributing%20claims%20to%20unnamed%20authorities%20instead%20of%20being%20specific.%20AI%20loves%20to%20invoke%20%22experts%22%2C%20%22observers%22%2C%20%22industry%20reports%22%2C%20and%20%22several%20publications%22%20without%20naming%20anyone.%20It%20also%20inflates%20the%20quantity%20of%20sources%20--%20presenting%20what%20one%20person%20said%20as%20a%20widely%20held%20view%2C%20or%20writing%20%22several%20publications%20have%20cited%22%20when%20it%20means%20two.%20If%20you%20can't%20name%20the%20expert%2C%20you%20don't%20have%20a%20source.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Experts%20argue%20that%20this%20approach%20has%20significant%20drawbacks.%22%0A-%20%22Industry%20reports%20suggest%20that%20adoption%20is%20accelerating.%22%0A-%20%22Observers%20have%20cited%20the%20initiative%20as%20a%20turning%20point.%22%0A%0A%23%23%23%20Invented%20Concept%20Labels%0A%0AAI%20clusters%20invented%20compound%20labels%20that%20sound%20analytical%20without%20being%20grounded.%20It%20appends%20abstract%20problem-nouns%20(paradox%2C%20trap%2C%20creep%2C%20divide%2C%20vacuum%2C%20inversion)%20to%20domain%20words%20%E2%80%94%20%22supervision%20paradox%22%2C%20%22acceleration%20trap%22%2C%20%22workload%20creep%22%20%E2%80%94%20and%20uses%20them%20as%20if%20they're%20established%2C%20rigorously%20defined%20terms.%20They%20function%20as%20rhetorical%20shorthand%3A%20name%20a%20thing%2C%20skip%20the%20argument.%20Multiple%20such%20labels%20in%20the%20same%20piece%20is%20a%20strong%20signal%20of%20AI%20slop.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22the%20supervision%20paradox%22%0A-%20%22the%20acceleration%20trap%22%0A-%20%22workload%20creep%22%0A%0A---%0A%0A%23%23%20Formatting%0A%0A%23%23%23%20Em-Dash%20Addiction%0A%0ACompulsive%20overuse%20of%20em%20dashes%20for%20dramatic%20pauses%2C%20parenthetical%20asides%20and%20pivot%20points.%20A%20human%20writer%20might%20use%202-3%20per%20piece%20(and%20naturally)%3B%20AI%20will%20use%2020%2B.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20problem%20--%20and%20this%20is%20the%20part%20nobody%20talks%20about%20--%20is%20systemic.%22%0A-%20%22The%20tinkerer%20spirit%20didn't%20die%20of%20natural%20causes%20--%20it%20was%20bought%20out.%22%0A-%20%22Not%20recklessly%2C%20not%20completely%20--%20but%20enough%20--%20enough%20to%20matter.%22%0A%0A%23%23%23%20Bold-First%20Bullets%0A%0AEvery%20bullet%20point%20or%20list%20item%20starts%20with%20a%20bolded%20phrase%20or%20sentence.%20Extremely%20common%20in%20Claude%20and%20ChatGPT%20markdown%20output.%20Almost%20nobody%20formats%20lists%20this%20way%20when%20writing%20by%20hand.%20It's%20a%20telltale%20sign%20of%20AI-generated%20documentation%20and%20blog%20posts%20AND%20README%20files%20(especially%20with%20emojis).%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Every%20single%20bullet%20point%20begins%20with%20a%20bold%20keyword.%22%0A-%20%22**Security**%3A%20Environment-based%20configuration%20with...%22%0A-%20%22**Performance**%3A%20Lazy%20loading%20of%20expensive%20resources...%22%0A%0A%23%23%23%20Unicode%20Decoration%0A%0AUse%20of%20unicode%20arrows%20(-%3E)%2C%20smart%2Fcurly%20quotes%2C%20and%20other%20special%20characters%20that%20can't%20be%20easily%20typed%20on%20a%20standard%20keyboard.%20Real%20writers%20typing%20in%20a%20text%20editor%20produce%20straight%20quotes%20and%20-%3E%20or%20%3D%3E.%20Claude%20in%20particular%20loves%20the%20-%3E%20arrow.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Input%20%E2%86%92%20Processing%20%E2%86%92%20Output%22%0A-%20%22This%20leads%20to%20better%20outcomes%20%E2%86%92%20which%20means%20higher%20engagement%22%0A-%20%22%E2%80%9CSmart%20quotes%E2%80%9D%20instead%20of%20straight%20%22quotes%22%20that%20you%E2%80%99d%20actually%20type%22%0A%0A---%0A%0A%23%23%20Composition%0A%0A%23%23%23%20Fractal%20Summaries%0A%0A%22What%20I'm%20going%20to%20tell%20you%3B%20what%20I'm%20telling%20you%3B%20what%20I%20just%20told%20you%22%20--%20applied%20at%20every%20level%20of%20the%20document.%20Every%20subsection%20gets%20a%20summary.%20Every%20section%20gets%20a%20summary.%20The%20document%20itself%20gets%20a%20summary.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22In%20this%20section%2C%20we'll%20explore...%20%5B3000%20words%20later%5D%20...as%20we've%20seen%20in%20this%20section.%22%0A-%20%22A%20conclusion%20that%20restates%20every%20point%20already%20made%20in%20the%20previous%203000%20words%22%0A-%20%22And%20so%20we%20return%20to%20where%20we%20began.%22%0A%0A%23%23%23%20The%20Dead%20Metaphor%0A%0ALatching%20onto%20a%20single%20metaphor%20and%20beating%20it%20into%20the%20ground%20across%20the%20entire%20thing.%20A%20human%20writer%20would%20introduce%20a%20metaphor%2C%20use%20it%20then%20move%20on.%20AI%20will%20repeat%20the%20same%20metaphor%205-10%20times.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20ecosystem%20needs%20ecosystems%20to%20build%20ecosystem%20value.%22%0A-%20%22Walls%20and%20doors%20used%2030%2B%20times%20in%20the%20same%20article%22%0A-%20%22Every%20paragraph%20finds%20a%20way%20to%20say%20%22primitives%22%20again%22%0A%0A%23%23%23%20Historical%20Analogy%20Stacking%0A%0AESPECIALLY%20COMMON%20IN%20TECHNICAL%20WRITING%3A%20Rapid-fire%20listing%20of%20historical%20companies%20or%20tech%20revolutions%20to%20build%20false%20authority.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Apple%20didn't%20build%20Uber.%20Facebook%20didn't%20build%20Spotify.%20Stripe%20didn't%20build%20Shopify.%20AWS%20didn't%20build%20Airbnb.%22%0A-%20%22Every%20major%20technological%20shift%20--%20the%20web%2C%20mobile%2C%20social%2C%20cloud%20--%20followed%20the%20same%20pattern.%22%0A-%20%22Take%20Spotify...%20Or%20consider%20Uber...%20Airbnb%20followed%20a%20similar%20path...%20Shopify%20is%20another%20example...%20Even%20Discord...%22%0A%0A%23%23%23%20One-Point%20Dilution%0A%0AMaking%20a%20single%20argument%20and%20restating%20it%20in%2010%20different%20ways%20across%20thousands%20of%20words.%20The%20model%20pads%20a%20simple%20thesis%20to%20feel%20%22comprehensive%22%20by%20rephrasing%20the%20same%20idea%20with%20different%20metaphors%2C%20examples%2C%20and%20framings.%20An%20800-word%20argument%20becomes%204000%20words%20of%20circular%20repetition.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20same%20point%2C%20restated%20eight%20ways%20across%204000%20words.%22%0A-%20%22Each%20section%20rephrases%20the%20thesis%20with%20a%20different%20metaphor%20but%20adds%20nothing%20new%22%0A%0A%23%23%23%20Content%20Duplication%0A%0ARepeating%20entire%20sections%20or%20paragraphs%20verbatim%20within%20the%20same%20piece.%20This%20happens%20when%20the%20model%20loses%20track%20of%20what%20it%20has%20already%20written%2C%20especially%20in%20longer%20pieces.%20A%20dead%20giveaway%20of%20unedited%20AI%20output.%20Less%20common%20nowadays.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22The%20same%20section%20appeared%20twice%2C%20word-for-word%20identical.%22%0A-%20%22Paragraph%203%20and%20paragraph%2017%20are%20the%20same%20sentence%20reworded%22%0A%0A%23%23%23%20The%20Signposted%20Conclusion%0A%0AExplicitly%20announcing%20the%20conclusion%20with%20%22In%20conclusion%22%2C%20%22To%20sum%20up%22%2C%20or%20%22In%20summary%22.%20Competent%20writing%20doesn't%20need%20to%20tell%20you%20it's%20concluding.%20The%20reader%20can%20feel%20it.%20AI%20signals%20its%20structural%20moves%20because%20it's%20following%20a%20template%2C%20not%20writing%20organically.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22In%20conclusion%2C%20the%20future%20of%20AI%20depends%20on...%22%0A-%20%22To%20sum%20up%2C%20we've%20explored%20three%20key%20themes...%22%0A-%20%22In%20summary%2C%20the%20evidence%20suggests...%22%0A%0A%23%23%23%20%22Despite%20Its%20Challenges...%22%0A%0AThe%20rigid%20formula%20where%20AI%20acknowledges%20problems%20only%20to%20immediately%20dismiss%20them.%20Always%20follows%20the%20same%20beat%3A%20%22Despite%20its%20%5Bpositive%20words%5D%2C%20%5Bsubject%5D%20faces%20challenges...%22%20then%20ends%20with%20%22Despite%20these%20challenges%2C%20%5Boptimistic%20conclusion%5D.%22.%0A%0A**Avoid%20patterns%20like%3A**%0A-%20%22Despite%20these%20challenges%2C%20the%20initiative%20continues%20to%20thrive.%22%0A-%20%22Despite%20its%20industrial%20and%20residential%20prosperity%2C%20Korattur%20faces%20challenges%20typical%20of%20urban%20areas.%22%0A-%20%22Despite%20their%20promising%20applications%2C%20pyroelectric%20materials%20face%20several%20challenges%20that%20must%20be%20addressed%20for%20broader%20adoption.%22%0A%0A---%0A%0ARemember%3A%20any%20of%20these%20patterns%20used%20once%20might%20be%20fine.%20The%20problem%20is%20when%0Amultiple%20tropes%20appear%20together%20or%20when%20a%20single%20trope%20is%20used%20repeatedly.%0AWrite%20like%20a%20human%3A%20varied%2C%20imperfect%2C%20specific." download="tropes.md" class="inline-flex items-center rounded-md border border-border px-4 py-2 text-sm font-medium transition-colors hover:bg-tag-bg">Download</a><a href="https://gist.github.com/ossa-ma/f3baa9d25154c33095e22272c631f5a1" target="_blank" rel="noopener noreferrer" aria-label="View on GitHub" class="inline-flex items-center rounded-md border border-border px-4 py-2 transition-colors hover:bg-tag-bg"></a></p></div><pre class="overflow-x-auto rounded-lg border border-border bg-surface p-6 text-xs leading-relaxed font-mono whitespace-pre-wrap text-muted"># AI Writing Tropes to Avoid
Add this file to your AI assistant's system prompt or context to help it avoid
common AI writing patterns. Source: [tropes.fyi](https://tropes.fyi) by [ossama.is](https://ossama.is)
---
## Word Choice
### "Quietly" and Other Magic Adverbs
Overuse of "quietly" and similar adverbs to convey subtle importance or understated power. AI reaches for these adverbs to make mundane descriptions feel significant. Also includes: "deeply", "fundamentally", "remarkably", "arguably".
**Avoid patterns like:**
- "quietly orchestrating workflows, decisions, and interactions"
- "the one that quietly suffocates everything else"
- "a quiet intelligence behind it"
### "Delve" and Friends
Used to be the most infamous AI tell. "Delve" went from an uncommon English word to appearing in a staggering percentage of AI-generated text. Part of a family of overused AI vocabulary including "certainly", "utilize", "leverage" (as a verb), "robust", "streamline", and "harness".
**Avoid patterns like:**
- "Let's delve into the details..."
- "Delving deeper into this topic..."
- "We certainly need to leverage these robust frameworks..."
### "Tapestry" and "Landscape"
Overuse of ornate or grandiose nouns where simpler words would do. "Tapestry" is used to describe anything interconnected. "Landscape" is used to describe any field or domain. Other offenders: "paradigm", "synergy", "ecosystem", "framework".
**Avoid patterns like:**
- "The rich tapestry of human experience..."
- "Navigating the complex landscape of modern AI..."
- "The ever-evolving landscape of technology..."
### The "Serves As" Dodge
Replacing simple "is" or "are" with pompous alternatives like "serves as", "stands as", "marks", or "represents". AI avoids basic copulas because its repetition penalty pushes it toward fancier constructions (I've studied this!).
**Avoid patterns like:**
- "The building serves as a reminder of the city's heritage."
- "Gallery 825 serves as LAAA's exhibition space for contemporary art."
- "The station marks a pivotal moment in the evolution of regional transit."
---
## Sentence Structure
### Negative Parallelism
The "It's not X -- it's Y" pattern, often with an em dash. The single most commonly identified AI writing tell. Man I f*cking hate it. AI uses this to create false profundity by framing everything as a surprising reframe. One in a piece can be effective; ten in a blog post is a genuine insult to the reader. Before LLMs, people simply did not write like this at scale. Includes the causal variant "not because X, but because Y" where every explanation is framed as a surprise reveal.
**Avoid patterns like:**
- "It's not bold. It's backwards."
- "Feeding isn't nutrition. It's dialysis."
- "Half the bugs you chase aren't in your code. They're in your head."
### "Not X. Not Y. Just Z."
The dramatic countdown pattern. AI builds tension by negating two or more things before revealing the actual point. Creates a false sense of narrowing down to the truth.
**Avoid patterns like:**
- "Not a bug. Not a feature. A fundamental design flaw."
- "Not ten. Not fifty. Five hundred and twenty-three lint violations across 67 files."
- "not recklessly, not completely, but enough"
### "The X? A Y."
Self-posed rhetorical questions answered immediately in the next sentence or clause. The model asks a question nobody was asking, then answers it for dramatic effect. Thinks this is the epitome of great writing.
**Avoid patterns like:**
- "The result? Devastating."
- "The worst part? Nobody saw it coming."
- "The scary part? This attack vector is perfect for developers."
### Anaphora Abuse
Repeating the same sentence opening multiple times in quick succession.
**Avoid patterns like:**
- "They assume that users will pay... They assume that developers will build... They assume that ecosystems will emerge... They assume that..."
- "They could expose... They could offer... They could provide... They could create... They could let... They could unlock..."
- "They have built engines, but not vehicles. They have built power, but not leverage. They have built walls, but not doors."
### Tricolon Abuse
Overuse of the rule-of-three pattern, often extended to four or five. A single tricolon is elegant; three back-to-back tricolons are a pattern recognition failure.
**Avoid patterns like:**
- "Products impress people; platforms empower them. Products solve problems; platforms create worlds. Products scale linearly; platforms scale exponentially."
- "identity, payments, compute, distribution"
- "workflows, decisions, and interactions"
### "It's Worth Noting"
Filler transitions that signal nothing. AI uses these phrases to introduce new points without actually connecting them to the previous argument. Also includes: "It bears mentioning", "Importantly", "Interestingly", "Notably".
**Avoid patterns like:**
- "It's worth noting that this approach has limitations."
- "Importantly, we must consider the broader implications."
- "Interestingly, this pattern repeats across industries."
### Superficial Analyses
Tacking a present participle ("-ing") phrase onto the end of a sentence to inject shallow analysis that says nothing. The model attaches significance, legacy, or broader meaning to mundane facts using phrases like "highlighting its importance", "reflecting broader trends", or "contributing to the development of...".
**Avoid patterns like:**
- "contributing to the region's rich cultural heritage"
- "This etymology highlights the enduring legacy of the community's resistance and the transformative power of unity in shaping its identity."
- "underscoring its role as a dynamic hub of activity and culture"
### False Ranges
Using "from X to Y" constructions where X and Y aren't on any real scale. In legitimate use, "from X to Y" implies a spectrum with a meaningful middle. AI uses it as a fancy way to list two loosely related things. "From innovation to cultural transformation" -- what's in between???? Nothing!
**Avoid patterns like:**
- "From innovation to implementation to cultural transformation."
- "From the singularity of the Big Bang to the grand cosmic web."
- "From problem-solving and tool-making to scientific discovery, artistic expression, and technological innovation."
### Gerund Fragment Litany
After making a claim, AI illustrates it with a stream of verbless gerund fragments — standalone sentences with no grammatical subject. "Fixing small bugs. Writing straightforward features. Implementing well-defined tickets." The first sentence already said everything. The fragments add nothing except word count and that familiar AI cadence. Humans don't write first drafts this way. It's a pure structural tic.
**Avoid patterns like:**
- "Fixing small bugs. Writing straightforward features. Implementing well-defined tickets."
- "Reviewing pull requests. Debugging edge cases. Attending architecture meetings."
- "Shipping faster. Moving quicker. Delivering more."
---
## Paragraph Structure
### Short Punchy Fragments
Excessive use of very short sentences or sentence fragments as standalone paragraphs for manufactured emphasis. RLHF training has pushed models toward "writing for readability" aimed at the lowest common denominator: one thought per sentence, no mental state-keeping required. It's an inhuman style. No real person writes first drafts this way because it doesn't match how humans think or speak.
**Avoid patterns like:**
- "He published this. Openly. In a book. As a priest."
- "These weren't just products. And the software side matched. Then it professionalised. But I adapted."
- "Platforms do."
### Listicle in a Trench Coat
Numbered or labeled points dressed up as continuous prose. The model writes what is essentially a listicle but wraps each point in a paragraph that starts with "The first... The second... The third..." to disguise the format. Perhaps you told it to stop generating lists and it decided to do this instead... still very common.
**Avoid patterns like:**
- "The first wall is the absence of a free, scoped API... The second wall is the lack of delegated access... The third wall is the absence of scoped permissions..."
- "The second takeaway is that... The third takeaway is that... The fourth takeaway is that..."
---
## Tone
### "Here's the Kicker"
False suspense transitions that promise a revelation but deliver a point that did NOT need the buildup. The model uses these phrases to manufacture drama before an otherwise unremarkable observation LOL. Also includes: "Here's the thing", "Here's where it gets interesting", "Here's what most people miss".
**Avoid patterns like:**
- "Here's the kicker."
- "Here's the thing about AI adoption."
- "Here's where it gets interesting."
### "Think of It As..."
The patronizing analogy. AI constantly reaches for "Think of it as..." or "It's like a..." to simplify concepts. The model defaults to teacher mode and assumes the reader needs a metaphor to understand anything. Often produces analogies that are less clear than the original concept.
**Avoid patterns like:**
- "Think of it like a highway system for data."
- "Think of it as a Swiss Army knife for your workflow."
- "It's like asking someone to buy a car they're only allowed to sit in while it's parked."
### "Imagine a World Where..."
The classic AI invitation to futurism. To sell the argument usually begins with "Imagine" followed by a list of wonderful things that will happen if the reader agrees with the premise.
**Avoid patterns like:**
- "Imagine a world where every tool you use -- your calendar, your inbox, your documents, your CRM, your code editor -- has a quiet intelligence behind it..."
- "In that world, workflows stop being collections of manual steps and start becoming orchestrations."
### False Vulnerability
Simulated self-awareness or honesty that reads as performative. The model pretends to break the fourth wall or admit a bias, creating a false sense of authenticity. Real vulnerability is specific and uncomfortable; AI vulnerability is polished and risk-free!!!!
**Avoid patterns like:**
- "And yes, I'm openly in love with the platform model"
- "And yes, since we're being honest: I'm looking at you, OpenAI, Google, Anthropic, Meta"
- "This is not a rant; it's a diagnosis"
### "The Truth Is Simple"
Asserting that something is obvious, clear or simple instead of actually proving it. If you have to tell the reader your point is clear, it very likely isn't.
**Avoid patterns like:**
- "The reality is simpler and less flattering"
- "History is unambiguous on this point"
- "History is clear, the metrics are clear, the examples are clear"
### Grandiose Stakes Inflation
Everything is the most important thing ever. AI inflates the stakes of every argument to world-historical significance. A blog post about API pricing becomes a meditation on the fate of civilization.
**Avoid patterns like:**
- "This will fundamentally reshape how we think about everything."
- "will define the next era of computing"
- "something entirely new"
### "Let's Break This Down"
The pedagogical voice that assumes the reader needs hand-holding. AI defaults to a teacher-student dynamic even when writing for expert audiences. Also includes: "Let's unpack this", "Let's explore", "Let's dive in".
**Avoid patterns like:**
- "Let's break this down step by step."
- "Let's unpack what this really means."
- "Let's explore this idea further."
### Vague Attributions
Attributing claims to unnamed authorities instead of being specific. AI loves to invoke "experts", "observers", "industry reports", and "several publications" without naming anyone. It also inflates the quantity of sources -- presenting what one person said as a widely held view, or writing "several publications have cited" when it means two. If you can't name the expert, you don't have a source.
**Avoid patterns like:**
- "Experts argue that this approach has significant drawbacks."
- "Industry reports suggest that adoption is accelerating."
- "Observers have cited the initiative as a turning point."
### Invented Concept Labels
AI clusters invented compound labels that sound analytical without being grounded. It appends abstract problem-nouns (paradox, trap, creep, divide, vacuum, inversion) to domain words — "supervision paradox", "acceleration trap", "workload creep" — and uses them as if they're established, rigorously defined terms. They function as rhetorical shorthand: name a thing, skip the argument. Multiple such labels in the same piece is a strong signal of AI slop.
**Avoid patterns like:**
- "the supervision paradox"
- "the acceleration trap"
- "workload creep"
---
## Formatting
### Em-Dash Addiction
Compulsive overuse of em dashes for dramatic pauses, parenthetical asides and pivot points. A human writer might use 2-3 per piece (and naturally); AI will use 20+.
**Avoid patterns like:**
- "The problem -- and this is the part nobody talks about -- is systemic."
- "The tinkerer spirit didn't die of natural causes -- it was bought out."
- "Not recklessly, not completely -- but enough -- enough to matter."
### Bold-First Bullets
Every bullet point or list item starts with a bolded phrase or sentence. Extremely common in Claude and ChatGPT markdown output. Almost nobody formats lists this way when writing by hand. It's a telltale sign of AI-generated documentation and blog posts AND README files (especially with emojis).
**Avoid patterns like:**
- "Every single bullet point begins with a bold keyword."
- "**Security**: Environment-based configuration with..."
- "**Performance**: Lazy loading of expensive resources..."
### Unicode Decoration
Use of unicode arrows (-&gt;), smart/curly quotes, and other special characters that can't be easily typed on a standard keyboard. Real writers typing in a text editor produce straight quotes and -&gt; or =&gt;. Claude in particular loves the -&gt; arrow.
**Avoid patterns like:**
- "Input → Processing → Output"
- "This leads to better outcomes → which means higher engagement"
- "“Smart quotes” instead of straight "quotes" that you’d actually type"
---
## Composition
### Fractal Summaries
"What I'm going to tell you; what I'm telling you; what I just told you" -- applied at every level of the document. Every subsection gets a summary. Every section gets a summary. The document itself gets a summary.
**Avoid patterns like:**
- "In this section, we'll explore... [3000 words later] ...as we've seen in this section."
- "A conclusion that restates every point already made in the previous 3000 words"
- "And so we return to where we began."
### The Dead Metaphor
Latching onto a single metaphor and beating it into the ground across the entire thing. A human writer would introduce a metaphor, use it then move on. AI will repeat the same metaphor 5-10 times.
**Avoid patterns like:**
- "The ecosystem needs ecosystems to build ecosystem value."
- "Walls and doors used 30+ times in the same article"
- "Every paragraph finds a way to say "primitives" again"
### Historical Analogy Stacking
ESPECIALLY COMMON IN TECHNICAL WRITING: Rapid-fire listing of historical companies or tech revolutions to build false authority.
**Avoid patterns like:**
- "Apple didn't build Uber. Facebook didn't build Spotify. Stripe didn't build Shopify. AWS didn't build Airbnb."
- "Every major technological shift -- the web, mobile, social, cloud -- followed the same pattern."
- "Take Spotify... Or consider Uber... Airbnb followed a similar path... Shopify is another example... Even Discord..."
### One-Point Dilution
Making a single argument and restating it in 10 different ways across thousands of words. The model pads a simple thesis to feel "comprehensive" by rephrasing the same idea with different metaphors, examples, and framings. An 800-word argument becomes 4000 words of circular repetition.
**Avoid patterns like:**
- "The same point, restated eight ways across 4000 words."
- "Each section rephrases the thesis with a different metaphor but adds nothing new"
### Content Duplication
Repeating entire sections or paragraphs verbatim within the same piece. This happens when the model loses track of what it has already written, especially in longer pieces. A dead giveaway of unedited AI output. Less common nowadays.
**Avoid patterns like:**
- "The same section appeared twice, word-for-word identical."
- "Paragraph 3 and paragraph 17 are the same sentence reworded"
### The Signposted Conclusion
Explicitly announcing the conclusion with "In conclusion", "To sum up", or "In summary". Competent writing doesn't need to tell you it's concluding. The reader can feel it. AI signals its structural moves because it's following a template, not writing organically.
**Avoid patterns like:**
- "In conclusion, the future of AI depends on..."
- "To sum up, we've explored three key themes..."
- "In summary, the evidence suggests..."
### "Despite Its Challenges..."
The rigid formula where AI acknowledges problems only to immediately dismiss them. Always follows the same beat: "Despite its [positive words], [subject] faces challenges..." then ends with "Despite these challenges, [optimistic conclusion].".
**Avoid patterns like:**
- "Despite these challenges, the initiative continues to thrive."
- "Despite its industrial and residential prosperity, Korattur faces challenges typical of urban areas."
- "Despite their promising applications, pyroelectric materials face several challenges that must be addressed for broader adoption."
---
Remember: any of these patterns used once might be fine. The problem is when
multiple tropes appear together or when a single trope is used repeatedly.
Write like a human: varied, imperfect, specific.</pre>]]></description>
      <link>https://tropes.fyi/tropes-md</link>
      <guid>https://tropes.fyi/tropes-md</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Company Contacts]]></title>
      <description><![CDATA[]]></description>
      <link>https://www.elliott.org/company-contacts/</link>
      <guid>https://www.elliott.org/company-contacts/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Qwen3.5 - How to Run Locally Guide | Unsloth Documentation]]></title>
      <description><![CDATA[but tons of ram, use a vm]]></description>
      <link>https://unsloth.ai/docs/models/qwen3.5</link>
      <guid>https://unsloth.ai/docs/models/qwen3.5</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[My Homelab Setup]]></title>
      <description><![CDATA[<div class="header-container" data-astro-cid-g5zn7x5n=""><p class="subtitle" data-astro-cid-g5zn7x5n="">How I repurposed my old gaming PC to set up a home server for data storage, backups, and self-hosted apps.</p><p> 6 min read</p><div class="hero-image-container" data-astro-cid-g5zn7x5n=""><figure class="hero-photo" data-astro-cid-f2nidmru=""><picture data-astro-cid-f2nidmru="true"><source srcset="/_astro/homelab-pc_Z1xeanV.jpg 600w, /_astro/homelab-pc_5Y3Ir.jpg 900w, /_astro/homelab-pc_Z2d5prt.jpg 1200w, /_astro/homelab-pc_u8YoU.jpg 1800w" type="image/jpeg" sizes="auto" /><img src="https://bryananthonio.com/_astro/homelab-pc_gpfF1.png" srcset="/_astro/homelab-pc_BLbEb.png 600w, /_astro/homelab-pc_2fYpLy.png 900w, /_astro/homelab-pc_Z1eu5v4.png 1200w, /_astro/homelab-pc_gpfF1.png 1800w" alt="A Fractal Design PC case with the side panel removed, showing an EVGA GeForce GTX 1070 Ti GPU and CPU cooler" sizes="auto" data-astro-cid-f2nidmru="true" width="1800" height="1200" class="hero-photo__img" /></picture><figcaption class="figcaption" data-astro-cid-f2nidmru="">My homelab PC</figcaption></figure></div></div><div class="blog-post-content prose blog-post-body" data-astro-cid-2q5oecfc=""><p>For the longest time, I’ve procrastinated on finding a good backup and storage solution for my Fujifilm RAW files. My solution up until recently involved manually copying my photos across two external SSD drives. This was quite a hassle and I hadn’t yet figured out a good off-site backup strategy.</p><p>After hearing constant news updates of how <a href="https://www.pcmag.com/news/memory-shortage-now-wreaking-havoc-on-hard-drive-prices-too">hard drive prices have been surging due to AI data center buildouts</a>, I finally decided to purchase some hard drives and set up a homelab to meet my storage and backup needs. I also used this opportunity to explore self-hosting some apps I’ve been eager to check out.</p><h2 id="contents">Contents</h2><ul><li><a href="#hardware">Hardware</a></li>
<li><a href="#truenas-operating-system">TrueNAS Operating System</a></li>
<li><a href="#apps-im-currently-self-hosting">Apps I’m Currently Self-hosting</a>
<ul><li><a href="#scrutiny">Scrutiny</a></li>
<li><a href="#backrest">Backrest</a></li>
<li><a href="#immich">Immich</a></li>
<li><a href="#mealie">Mealie</a></li>
<li><a href="#ollama">Ollama</a></li>
</ul></li>
<li><a href="#remote-access">Remote Access</a></li>
<li><a href="#next-steps">Next Steps</a></li>
</ul><h2 id="hardware">Hardware</h2><p>I repurposed my old gaming PC I built back in 2018 for this use case. This machine has the following specs:</p><table><thead><tr><th>Component</th>
<th>Product</th>
</tr></thead><tbody><tr><td>CPU</td>
<td><a href="https://www.techpowerup.com/cpu-specs/ryzen-5-2600x.c2014">AMD Ryzen 5 2600X 3.6 GHz 6-Core Processor</a></td>
</tr><tr><td>Motherboard</td>
<td><a href="https://www.asrock.com/mb/amd/b450%20pro4/index.asp">ASRock B450 Pro4 ATX AM4</a></td>
</tr><tr><td>RAM</td>
<td><a href="https://www.gskill.com/product/165/170/1535961634/F4-3200C14D-16GFX-EOL">G.Skill Flare X 16 GB (2 x 8 GB) DDR4-3200 CL14</a></td>
</tr><tr><td>GPU</td>
<td><a href="https://www.evga.com/products/specs/gpu.aspx?pn=649ba262-3f05-4ff8-9756-9cdc206e7ce6">EVGA FTW2 GAMING iCX GeForce GTX 1070 Ti 8 GB</a></td>
</tr><tr><td>Case</td>
<td><a href="https://www.fractal-design.com/products/cases/meshify/meshify-c/">Fractal Design Meshify C ATX Mid Tower</a></td>
</tr><tr><td>PSU</td>
<td><a href="https://seasonic.com/prime-gold/">SeaSonic PRIME Gold 650 W 80+ Gold</a></td>
</tr><tr><td>Storage (HDD)</td>
<td>2x <a href="https://www.westerndigital.com/products/internal-drives/wd-red-plus-sata-3-5-hdd?sku=WD80EFPX">Western Digital Red Plus 8 TB 3.5”</a></td>
</tr><tr><td>Storage (SSD)</td>
<td><a href="https://www.samsung.com/us/computing/memory-storage/solid-state-drives/ssd-850-evo-2-5-sata-iii-500gb-mz-75e500b-am/">Samsung 850 Evo 500 GB 2.5”</a></td>
</tr><tr><td>Storage (NVMe)</td>
<td><a href="https://www.sandisk.com/en-gb/products/ssd/internal-ssd/wd-blue-sn550-nvme-ssd?sku=WDS500G2B0C-00PXH0">Western Digital Blue SN550 500 GB M.2-2280</a></td>
</tr></tbody></table><p>I purchased the Western Digital hard drives over the winter holiday break. The other components were already installed on the machine when I originally built it.</p><h2 id="truenas-operating-system">TrueNAS Operating System</h2><p>On this machine I installed <a href="https://www.truenas.com/truenas-community-edition/">TrueNAS Community Edition</a> on my NVMe drive. It’s a Linux-based operating system that is well-tailored for network-attached storage (NAS), file storage that is accessible to any device on your network.</p><figure class="figure screenshot screenshot--styled" data-astro-cid-w3o46csb=""><img src="https://bryananthonio.com/_astro/truenas-dashboard_6BIlH.webp" srcset="/_astro/truenas-dashboard_c5wnm.webp 600w, /_astro/truenas-dashboard_1HUCIA.webp 900w, /_astro/truenas-dashboard_KDXeG.webp 1200w, /_astro/truenas-dashboard_Z1kslM3.webp 1800w" alt="The TrueNAS Community Edition dashboard showing system information, CPU usage, and memory stats" sizes="auto" data-astro-cid-w3o46csb="true" width="3014" height="1680" class="screenshot__img" /><figcaption class="figcaption" data-astro-cid-w3o46csb="">My TrueNAS dashboard running version 25.10.1 (Goldeye)</figcaption></figure><p>For instance, TrueNAS allows you to create snapshots of your data. This is great for preventing data loss. If, for example, you accidentally deleted a file, you could recover it from a previous snapshot containing that file. In other words, a file is only truly deleted if and only if the system has no snapshots containing that file.</p><p>I’ve set up my machine to take hourly, daily, and even weekly snapshots. I’ve also configured it to delete old snapshots after a given period of time to save storage space.</p><p>Most of my data is mirrored across the two 8 TB hard disks in a RAID 1 setup. This means that if one drive fails, the other drive will still have all of my data intact. The SSD is used to store data from services that I self-host that benefit from having fast read and write speeds.</p><h2 id="apps-im-currently-self-hosting">Apps I’m Currently Self-hosting</h2><p>Not only is TrueNAS good for file storage, you can also host apps on it! <a href="https://apps.truenas.com/catalog/">TrueNAS offers a catalog of apps</a>, supported by the community, that you can install on your machine.</p><h3 id="scrutiny">Scrutiny</h3><p><a href="https://github.com/Starosdev/scrutiny">Scrutiny</a> is a web dashboard for monitoring the health of your storage drives. Hard drives and SSDs have built-in firmware called S.M.A.R.T. (Self-Monitoring, Analysis, and Reporting Technology) that continuously tracks health metrics like temperature, power-on hours, and read errors.</p><p>Scrutiny reads this data and presents it in a dashboard showing historical trends, making it easy to spot warning signs that a drive may fail soon.</p><figure class="figure screenshot screenshot--styled" data-astro-cid-w3o46csb=""><img src="https://bryananthonio.com/_astro/scrutiny-dashboard_ZOyVNT.webp" srcset="/_astro/scrutiny-dashboard_ZWqw9.webp 600w, /_astro/scrutiny-dashboard_HGswH.webp 900w, /_astro/scrutiny-dashboard_2nnwiG.webp 1200w, /_astro/scrutiny-dashboard_2727LG.webp 1800w" alt="Scrutiny drive health dashboard showing four drives — two 7.3 TiB HDDs, one SSD, and one NVMe — all with a passed status" sizes="auto" data-astro-cid-w3o46csb="true" width="2378" height="1708" class="screenshot__img" /><figcaption class="figcaption" data-astro-cid-w3o46csb="">Scrutiny monitoring all four of my drives</figcaption></figure><h3 id="backrest">Backrest</h3><p><a href="https://garethgeorge.github.io/backrest/">Backrest</a> is a web frontend for <a href="https://restic.net">restic</a>, a command-line tool used for creating file backups. I’ve set this up to save daily backups of my data to an object storage bucket on <a href="https://www.backblaze.com/cloud-storage">Backblaze B2</a>.</p><figure class="figure screenshot screenshot--styled" data-astro-cid-w3o46csb=""><img src="https://bryananthonio.com/_astro/backrest-dashboard_1ArxY9.webp" srcset="/_astro/backrest-dashboard_Z1arrMq.webp 600w, /_astro/backrest-dashboard_2hB3nx.webp 900w, /_astro/backrest-dashboard_2tQ7I5.webp 1200w, /_astro/backrest-dashboard_2ugQaW.webp 1800w" alt="The Backrest dashboard summary showing backup stats for a media-backup repository and plan" sizes="auto" data-astro-cid-w3o46csb="true" width="3014" height="1680" class="screenshot__img" /><figcaption class="figcaption" data-astro-cid-w3o46csb="">My Backrest configuration</figcaption></figure><h3 id="immich">Immich</h3><p><a href="https://immich.app">Immich</a> is one of the most popular open-source self-hosted apps for managing photos and videos. I love that it also offers <a href="https://apps.apple.com/us/app/immich/id1613945652">iOS</a> and <a href="https://play.google.com/store/apps/details?id=app.alextran.immich&amp;hl=en_US">Android</a> apps that allow you to back up photos and videos from your mobile devices. This is great if you want to rely less on services like Google Photos or iCloud. I’m currently using this to back up photos and videos from my phone.</p><figure class="figure screenshot screenshot--styled" data-astro-cid-w3o46csb=""><img src="https://bryananthonio.com/_astro/immich-dashboard_Z6oGg0.webp" srcset="/_astro/immich-dashboard_1xS828.webp 600w, /_astro/immich-dashboard_1INq07.webp 900w, /_astro/immich-dashboard_Zlveda.webp 1200w, /_astro/immich-dashboard_1gbJzC.webp 1800w" alt="Immich photo library showing a grid of bird photos." sizes="auto" data-astro-cid-w3o46csb="true" width="3014" height="1710" class="screenshot__img" /><figcaption class="figcaption" data-astro-cid-w3o46csb="">A sample of my Immich photo library</figcaption></figure><h3 id="mealie">Mealie</h3><p><a href="https://mealie.io">Mealie</a> is a recipe management tool that has made my meal prepping experience so much better! I’ve found it great for saving recipes I find on sites like <a href="https://cooking.nytimes.com">NYT Cooking</a>.</p><p>When importing recipes, you can provide the URL of the recipe and Mealie will scrape the ingredients and instructions from the page and save it in your recipe library. This makes it easier to keep track of recipes you find online and want to try out later.</p><figure class="figure screenshot screenshot--styled" data-astro-cid-w3o46csb=""><img src="https://bryananthonio.com/_astro/mealie-dashboard_Z1KbX6o.webp" srcset="/_astro/mealie-dashboard_2nYfCz.webp 600w, /_astro/mealie-dashboard_Z1ebp1B.webp 900w, /_astro/mealie-dashboard_2fN2EI.webp 1200w, /_astro/mealie-dashboard_ZaA37v.webp 1800w" alt="Mealie’s recipe library showing six saved recipes in a grid layout" sizes="auto" data-astro-cid-w3o46csb="true" width="3014" height="1696" class="screenshot__img" /><figcaption class="figcaption" data-astro-cid-w3o46csb="">A few of my saved recipes in Mealie</figcaption></figure><h3 id="ollama">Ollama</h3><p><a href="https://ollama.com">Ollama</a> is a backend for running various AI models. I installed it to try running large language models like <a href="https://ollama.com/library/qwen3.5:4b"><code>qwen3.5:4b</code></a> and <a href="https://ollama.com/library/gemma3:4b"><code>gemma3:4b</code></a> out of curiosity. I’ve also recently been exploring the world of vector embeddings such as <a href="https://ollama.com/library/qwen3-embedding:4b"><code>qwen3-embedding:4b</code></a>. All of these models are small enough to fit in the 8GB of VRAM my GPU provides. I like being able to offload the work of running models on my homelab instead of my laptop.</p><h2 id="remote-access">Remote Access</h2><p>When I’m not at home, I use <a href="https://tailscale.com">Tailscale</a>, a plug-and-play VPN service, to access my data and self-hosted apps remotely from any device. Tailscale builds on top of another tool called <a href="https://www.wireguard.com">WireGuard</a> to provide a secure tunnel into my home network.</p><p>The advantage here is that my homelab PC doesn’t need to be exposed to the public internet for this to work. Any device I want to use to access my homelab remotely needs to install the Tailscale app and be authenticated to my Tailscale network.</p><h2 id="next-steps">Next Steps</h2><p>Right now, accessing my apps requires typing in the IP address of my machine (or Tailscale address) together with the app’s port number. Because all of my services share the same IP address, my password manager has trouble distinguishing which login to use for each one.</p><p>In the future I’ll look into figuring out how to assign custom domain names to all of my services.</p><h3 class="section-label" data-astro-cid-2q5oecfc="">Tags</h3><p><a href="https://bryananthonio.com/blog/tags/homelab/" class="tag-chip md" data-astro-cid-q2wpt7bd="">homelab</a> <a href="https://bryananthonio.com/blog/tags/self-hosting/" class="tag-chip md" data-astro-cid-q2wpt7bd="">self-hosting</a></p></div>]]></description>
      <link>https://bryananthonio.com/blog/my-homelab-setup/</link>
      <guid>https://bryananthonio.com/blog/my-homelab-setup/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Can coding agents relicense open source through a “clean room” implementation of code?]]></title>
      <description><![CDATA[<p>Over the past few months it’s become clear that coding agents are extraordinarily good at building a weird version of a “clean room” implementation of code.</p><p>The most famous version of this pattern is when Compaq created a clean-room clone of the IBM BIOS back <a href="https://en.wikipedia.org/wiki/Compaq#Introduction_of_Compaq_Portable">in 1982</a>. They had one team of engineers reverse engineer the BIOS to create a specification, then handed that specification to another team to build a new ground-up version.</p><p>This process used to take multiple teams of engineers weeks or months to complete. Coding agents can do a version of this in hours—I experimented with a variant of this pattern against <a href="https://simonwillison.net/2025/Dec/15/porting-justhtml/">JustHTML</a> back in December.</p><p>There are a <em>lot</em> of open questions about this, both ethically and legally. These appear to be coming to a head in the venerable <a href="https://github.com/chardet/chardet">chardet</a> Python library.</p><p><code>chardet</code> was created by Mark Pilgrim <a href="https://pypi.org/project/chardet/1.0/">back in 2006</a> and released under the LGPL. Mark retired from public internet life in 2011 and chardet’s maintenance was taken over by others, most notably Dan Blanchard who has been responsible for every release since <a href="https://pypi.org/project/chardet/1.1/">1.1 in July 2012</a>.</p><p>Two days ago Dan released <a href="https://github.com/chardet/chardet/releases/tag/7.0.0">chardet 7.0.0</a> with the following note in the release notes:</p><blockquote>
<p>Ground-up, MIT-licensed rewrite of chardet. Same package name, same public API — drop-in replacement for chardet 5.x/6.x. Just way faster and more accurate!</p>
</blockquote><p>Yesterday Mark Pilgrim opened <a href="https://github.com/chardet/chardet/issues/327">#327: No right to relicense this project</a>:</p><blockquote>
<p>[...] First off, I would like to thank the current maintainers and everyone who has contributed to and improved this project over the years. Truly a Free Software success story.</p>
<p>However, it has been brought to my attention that, in the release <a href="https://github.com/chardet/chardet/releases/tag/7.0.0">7.0.0</a>, the maintainers claim to have the right to “relicense” the project. They have no such right; doing so is an explicit violation of the LGPL. Licensed code, when modified, must be released under the same LGPL license. Their claim that it is a “complete rewrite” is irrelevant, since they had ample exposure to the originally licensed code (i.e. this is not a “clean room” implementation). Adding a fancy code generator into the mix does not somehow grant them any additional rights.</p>
</blockquote><p>Dan’s <a href="https://github.com/chardet/chardet/issues/327#issuecomment-4005195078">lengthy reply</a> included:</p><blockquote>
<p>You’re right that I have had extensive exposure to the original codebase: I’ve been maintaining it for over a decade. A traditional clean-room approach involves a strict separation between people with knowledge of the original and people writing the new implementation, and that separation did not exist here.</p>
<p>However, the purpose of clean-room methodology is to ensure the resulting code is not a derivative work of the original. It is a means to an end, not the end itself. In this case, I can demonstrate that the end result is the same — the new code is structurally independent of the old code — through direct measurement rather than process guarantees alone.</p>
</blockquote><p>Dan goes on to present results from the <a href="https://github.com/jplag/JPlag">JPlag</a> tool—which describes itself as “State-of-the-Art Source Code Plagiarism &amp; Collusion Detection”—showing that the new 7.0.0 release has a max similarity of 1.29% with the previous release and 0.64% with the 1.1 version. Other release versions had similarities more in the 80-93% range.</p><p>He then shares critical details about his process, highlights mine:</p><blockquote>
<p>For full transparency, here’s how the rewrite was conducted. I used the <a href="https://github.com/obra/superpowers">superpowers</a> brainstorming skill to create a <a href="https://github.com/chardet/chardet/commit/f51f523506a73f89f0f9538fd31be458d007ab93">design document</a> specifying the architecture and approach I wanted based on the following requirements I had for the rewrite [...]</p>
<p><strong>I then started in an empty repository with no access to the old source tree, and explicitly instructed Claude not to base anything on LGPL/GPL-licensed code</strong>. I then reviewed, tested, and iterated on every piece of the result using Claude. [...]</p>
<p>I understand this is a new and uncomfortable area, and that using AI tools in the rewrite of a long-standing open source project raises legitimate questions. But the evidence here is clear: 7.0 is an independent work, not a derivative of the LGPL-licensed codebase. The MIT license applies to it legitimately.</p>
</blockquote><p>Since the rewrite was conducted using Claude Code there are a whole lot of interesting artifacts available in the repo. <a href="https://github.com/chardet/chardet/blob/925bccbc85d1b13292e7dc782254fd44cc1e7856/docs/plans/2026-02-25-chardet-rewrite-plan.md">2026-02-25-chardet-rewrite-plan.md</a> is particularly detailed, stepping through each stage of the rewrite process in turn—starting with the tests, then fleshing out the planned replacement code.</p><p>There are several twists that make this case particularly hard to confidently resolve:</p><ul><li>Dan has been immersed in chardet for over a decade, and has clearly been strongly influenced by the original codebase.</li>
<li>There is one example where Claude Code referenced parts of the codebase while it worked, as shown in <a href="https://github.com/chardet/chardet/blob/925bccbc85d1b13292e7dc782254fd44cc1e7856/docs/plans/2026-02-25-chardet-rewrite-plan.md#task-3-encoding-registry">the plan</a>—it looked at <a href="https://github.com/chardet/chardet/blob/f0676c0d6a4263827924b78a62957547fca40052/chardet/metadata/charsets.py">metadata/charsets.py</a>, a file that lists charsets and their properties expressed as a dictionary of dataclasses.</li>
<li>More complicated: Claude itself was very likely trained on chardet as part of its enormous quantity of training data—though we have no way of confirming this for sure. Can a model trained on a codebase produce a morally or legally defensible clean-room implementation?</li>
<li>As discussed in <a href="https://github.com/chardet/chardet/issues/36">this issue from 2014</a> (where Dan first openly contemplated a license change) Mark Pilgrim’s original code was a manual port from C to Python of Mozilla’s MPL-licensed character detection library.</li>
<li>How significant is the fact that the new release of chardet used the same PyPI package name as the old one? Would a fresh release under a new name have been more defensible?</li>
</ul><p>I have no idea how this one is going to play out. I’m personally leaning towards the idea that the rewrite is legitimate, but the arguments on both sides of this are entirely credible.</p><p>I see this as a microcosm of the larger question around coding agents for fresh implementations of existing, mature code. This question is hitting the open source world first, but I expect it will soon start showing up in Compaq-like scenarios in the commercial world.</p><p>Once commercial companies see that their closely held IP is under threat I expect we’ll see some well-funded litigation.</p><p><strong>Update 6th March 2026</strong>: A detail that’s worth emphasizing is that Dan does <em>not</em> claim that the new implementation is a pure “clean room” rewrite. Quoting <a href="https://github.com/chardet/chardet/issues/327#issuecomment-4005195078">his comment</a> again:</p><blockquote>
<p>A traditional clean-room approach involves a strict separation between people with knowledge of the original and people writing the new implementation, and that separation did not exist here.</p>
</blockquote><p>I can’t find it now, but I saw a comment somewhere that pointed out the absurdity of Dan being blocked from working on a new implementation of character detection as a result of the volunteer effort he put into helping to maintain an existing open source library in that domain.</p><p>I enjoyed Armin’s take on this situation in <a href="https://lucumr.pocoo.org/2026/3/5/theseus/">AI And The Ship of Theseus</a>, in particular:</p><blockquote>
<p>There are huge consequences to this. When the cost of generating code goes down that much, and we can re-implement it from test suites alone, what does that mean for the future of software? Will we see a lot of software re-emerging under more permissive licenses? Will we see a lot of proprietary software re-emerging as open source? Will we see a lot of software re-emerging as proprietary?</p>
</blockquote>]]></description>
      <link>https://simonwillison.net/2026/Mar/5/chardet/</link>
      <guid>https://simonwillison.net/2026/Mar/5/chardet/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[TerraInk]]></title>
      <description><![CDATA[]]></description>
      <link>https://terraink.app/</link>
      <guid>https://terraink.app/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[[untitled]]]></title>
      <description><![CDATA[<p>In early December 2023, I wrote a drawing program called <a href="https://internet-janitor.itch.io/wigglypaint">WigglyPaint</a> and published it on Itch.io.</p>
<p>All the drawing tools in WigglyPaint are animated, providing a live, automatic <a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/LineBoil">Line Boil</a> effect:</p>
<figure><img src="https://beyondloom.com/blog/onwigglypaint-figures/simpledrawing.gif" alt="" /></figure><p>Internally, WigglyPaint maintains three image buffers and edits them simultaneously, with different types of randomization applied for different drawing tools; many tools apply a random position offset between stroke segments or randomly select different brush shapes and sizes:</p>
<figure><img src="https://beyondloom.com/blog/onwigglypaint-figures/threeframes.gif" alt="" /></figure><p>We cycle through displaying the buffers at roughly 12 frames per second- a familiar speed for limited animation- though the drawing itself is processed more responsively. Three frames is something of a sweet spot: using only two frames produces an unpleasant jittering effect, and more than three frames offer a diminishing addition of fluidity:</p>
<figure><img src="https://beyondloom.com/blog/onwigglypaint-figures/framecounts.gif" alt="" /></figure><p>WigglyPaint is far from the first example of a drawing program that automatically introduces line boil; as I note in my Readme, it has some similarity to <a href="https://studionokoi.itch.io/shake-art-deluxe">Shake Art Deluxe</a> from 2022. The details of these tools are very different, though; <em>Shake Art</em> is vector-oriented, and continuously offsets control points for line-segments on screen. Individual lines can have different oscillation intensities and rates, with continuously variable settings for every parameter and a full hue-saturation-value gamut for color.</p>
<p>In WigglyPaint, I chose a design philosophy of strongly discretizing choices: good defaults, a few interesting options, no infinite combinatoric landscapes. Every drawing tool has a distinct personality. Instead of offering the millions of subtly varied colors available in a general-purpose drawing program, WigglyPaint offers five colors at a time- lineart, background, and three “markers”- with a range of striking, opinionated preset palettes:</p>
<figure><img src="https://beyondloom.com/blog/onwigglypaint-figures/palettes.gif" alt="" /></figure><p>Instead of an infinite undo history, WigglyPaint has a single “Oops” button. From a technical perspective, more undo levels would be easy to furnish. No undo levels <em>at all</em> can be truly infuriating, especially on touch-based devices that occasionally register spurious lines. A single undo level is just enough: it encourages a sense of <em>committing to forward momentum</em> on a drawing.</p>
<p>One particularly clever- if simple- idea I incorporated is to make the “markers” always draw <em>underneath</em> lineart:</p>
<figure><img src="https://beyondloom.com/blog/onwigglypaint-figures/underpainting.gif" alt="" /></figure><p>This offers the kind of drawing workflow that an artist might normally accomplish through <em>layered</em> drawing tools like <em>Photoshop</em> without the complexity of a UI for creating, reordering, flattening, grouping, or destroying layers, nor the mental overhead of switching between layers over the course of a project.</p>
<p>By virtue of being built in <a href="https://beyondloom.com/decker/index.html">Decker</a>, WigglyPaint has another set of tricks up its sleeve that none of its peers can match: if something you want isn’t there, it’s trivial to reach in and <em>add it live</em>. Here I use Decker’s editing tools to create a new brush shape from scratch in a few seconds:</p>
<figure><img src="https://beyondloom.com/blog/onwigglypaint-figures/custombrush.gif" alt="" /></figure><p>I think WigglyPaint’s good defaults and discrete choices are a big part of the appeal of the tool. Many users have commented that it’s great at helping them break out of artist’s block and relearn how to work fast and loose. Your drawings will never be <em>perfect</em>, so you can just embrace imperfection and make it a strength.</p>
<p>WigglyPaint’s initial release was quietly positive, especially within the Decker user community and on the now-defunct Eggbug-Oriented social media site <em>Cohost</em>. It was very rewarding to see the occasional user avatar with WigglyPaint’s unmistakable affectation, and the slow, steady trickle of wiggly artwork left in the Itch.io comment thread for the tool. As an experiment, I cross-published the tool on NewGrounds; it’s a much tougher crowd there than on Itch.io, but a few people seemed to enjoy it. If that’s where WigglyPaint’s story had tapered off into obscurity, I would’ve been perfectly satisfied.</p>
<p>After more than a year of quietly languishing, I glanced at my Itch.io analytics page one day and noticed a massive spike in traffic to WigglyPaint. As I would slowly piece together, WigglyPaint had become an overnight phenomenon among artists on Asian social media. The mostly-wordless approachability of the tool- combined with a strong, recognizable aesthetic- hit just the right notes. I went from a userbase of perhaps a few hundred mostly-North-American wigglypainters to <em>millions</em> internationally.</p>
<p>There is, perhaps, a version of this story where I rode the success of my scrappy little tool to personal fame and financial stability, but I simply don’t have the heart for it. I often feel that the people who <em>most</em> stand to benefit from the creative tools I build are the ones who wouldn’t be able to afford them if I charged money. WigglyPaint is and always will be <strong>free</strong> on top of its radically open-source, malleable nature.</p>
<p>I see most of the programs I build with Decker as a sort of software ambassadors for the future I’d like to see. I offer them as gifts.</p>
<hr /><p>If you search your favorite (or least-despised) social media or video sharing site, you can probably find quite a few <code>#wigglypaint</code> posts; countless users are enjoying WigglyPaint and actively posting their drawings, sometimes streaming themselves or even drawing wiggly commission pieces for one another. It’s wonderful to see this human creativity on display, and I’m truly happy for those users.</p>
<p>There’s one little problem, though. If you know what to look for, almost all of those videos, streams, and screenshots are visibly of WigglyPaint <a href="https://internet-janitor.itch.io/wigglypaint/devlog/678137/v13">v1.3</a>, which at time of writing was released well over a year ago. Last month I released <a href="https://internet-janitor.itch.io/wigglypaint/devlog/1355206/v15">v1.5</a>. If so many people are enjoying WigglyPaint, why are so many of them using such an old version?</p>
<p>If you use a general search engine to simply look for <code>WigglyPaint</code>, you’ll see your answer. Right at the top of the results are <code>wigglypaint.com</code>, <code>wigglypaint.art</code>, <code>wigglypaint.org</code>, <code>wigglypaint.net</code>, <code>wiggly-paint.com</code>, and half a dozen more variations. Most offer WigglyPaint, front-and-center, usually an unmodified copy of v1.3, sometimes with some minor “premium features” glued onto the side or my bylines peeled off. If you dig around on these sites, you can read about all sorts of fantastic WigglyPaint features, some of which even actually do exist. Some sites claim to be made by “fans of WigglyPaint”, and some even claim to be made by me, <em>with love</em>. Many have a donation box to shake, asking users to kindly donate to help “the creators”. Perhaps if you sign up for a subscription you can unlock <em>premium features</em> like a different color-picker or a dedicated wiggly-art posting zone?</p>
<p>I want to be absolutely clear here: <strong>NONE of these sites are created by me, or with anything remotely resembling my permission.</strong></p>
<p>The sites are <em>slop</em>; slapdash imitations pieced together with the help of so-called “Large Language Models” (LLMs). The closer you look at them, the stranger they appear, full of vague, repetitive claims, outright false information, and plenty of unattributed (stolen) art. This is what LLMs are best at: quickly fabricating plausible simulacra of real objects to mislead the unwary. It is no surprise that the same people who have total contempt for authorship find LLMs useful; every LLM and generative model today is constructed by consuming almost unimaginably massive quantities of human creative work- writing, drawings, code, music- and then regurgitating them piecemeal without attribution, <em>just different enough</em> to hide where it came from (usually). LLMs are sharp tools in the hands of plagiarists, con-men, spammers, and everyone who believes that creative expression is worthless. People who <em>extract</em> from the world instead of contributing to it.</p>
<p>It is humiliating and infuriating to see my work stolen by slop enthusiasts, and worse, used to mislead artists into paying scammers for something that ought to be free.</p>
<p>It’s not just websites where you can find stolen copies of WigglyPaint for sale, either. Plenty of clowns have crudely shoved my tool into a WebView wrapper and started trying to sell “The App Version of WigglyPaint” for iOS or Android, carefully phrasing their app store summaries with just enough ambiguity to imply- without <em>technically</em> saying so- that gullible users who give them a few dollars are helping support me. The subtler, deeper insult is the way these “ports” seal off Decker’s editing tools, preventing paid users from being able to reshape or customize WigglyPaint and make it their own. As usual, mobile users get a locked-down, mutilated appliance for their money instead of empowerment.</p>
<hr /><p>No one facet of WigglyPaint is particularly complex; a few paragraphs into this article you already knew everything essential about achieving its signature flavor of line-boil. Discounting the invisibly discarded prototypes and false-alleys I went down over the course of its development, WigglyPaint’s scripts are only a few hundred lines of code. I hope I’ve managed to convey here that the design, while simple, is very <em>intentional</em> in non-obvious ways, and that the whole of the application is rather more than the sum of its parts.</p>
<p>It would be fine if people were building their own riffs on WigglyPaint’s ideas; they’re <em>just ideas</em>. It would be easy to create something new from these ideas, but the thieves can’t be bothered to add even the tiniest creative spark of their own.</p>
<p>The only reward I ever wanted for projects like WigglyPaint is a chance to grow my audience, and share my projects with more people. Since so much of my hypothetical userbase is unwittingly using stolen copies of WigglyPaint, and sharing links to the same slop sites they were linked to- and so on, and so forth- they’ll never know about any of my other projects. They won’t see updates I publish, or documentation I revise. I have been erased.</p>
<p>The most wildly successful project I’ve ever released is no longer mine. In all my years of building things and sharing them online, I have never felt so <em>violated</em>.</p>
<p>That’s all.</p>
<p><a href="https://beyondloom.com/blog/index.html">back</a></p>]]></description>
      <link>https://beyondloom.com/blog/onwigglypaint.html</link>
      <guid>https://beyondloom.com/blog/onwigglypaint.html</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[We’re Training Students To Write Worse To Prove They’re Not Robots, And It’s Pushing Them To Use More AI | Techdirt]]></title>
      <description><![CDATA[<h3>from the <em>can-someone-ask-an-ai-about-incentives</em> dept</h3><p>Fri, Mar 6th 2026 03:13pm -</p><p>About a year and a half ago, I wrote about <a href="https://www.techdirt.com/2024/09/04/ai-checkers-forcing-kids-to-write-like-a-robot-to-avoid-being-called-a-robot/">my kid’s experience with an AI checker tool</a> that was pre-installed on a school-issued Chromebook. The assignment had been to write an essay about Kurt Vonnegut’s <em>Harrison Bergeron</em>—a story about a dystopian society that enforces “equality” by handicapping anyone who excels—and the AI detection tool flagged the essay as “18% AI written.” The culprit? Using the word “devoid.” When the word was swapped out for “without,” the score magically dropped to 0%.</p><p>The irony of being forced to dumb down an essay about a story warning against the forced suppression of excellence was not lost on me. Or on my kid, who spent a frustrating afternoon removing words and testing sentences one at a time, trying to figure out what invisible tripwire the algorithm had set. The lesson the kid absorbed was clear: write less creatively, use simpler vocabulary, and don’t sound <em>too</em> good, because sounding good is now suspicious.</p><p>At the time, I worried this was going to become a much bigger problem. That the fear of AI “cheating” would create a culture that actively punished good writing and pushed students toward mediocrity. I was hoping I’d be wrong about that.</p><p>Turns out… I was not wrong.</p><p>Dadland Maye, a writing instructor who has taught at many universities, has <a href="https://www.chronicle.com/article/ai-detection-pushed-my-students-to-use-ai">published a piece in the Chronicle of Higher Education</a> documenting exactly how this has played out across his classrooms—and it’s even worse than what I described. Because the AI detection regime hasn’t just pushed students to write worse. It has actively pushed students who <em>never used AI</em> to start using it.</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>This fall, a student told me she began using generative AI only after learning that stylistic features such as em dashes were rumored to trigger AI detectors. To protect herself from being flagged, she started running her writing through AI tools to see how it would register.</em></p>
</blockquote><p>A student who was writing her own work, with her own words, started using AI tools <em>defensively</em>—not to cheat, but to make sure her own writing wouldn’t be accused of cheating. The tool designed to prevent AI use became the reason she started using AI.</p><p>This is the <a href="https://www.historic-uk.com/HistoryUK/HistoryofBritain/Cobra-Effect/">Cobra Effect</a> in its purest form. The British colonial government in India offered a bounty for dead cobras to reduce the cobra population. People started breeding cobras to collect the bounty. When the government scrapped the program, the breeders released their now-worthless cobras, making the problem worse than before. AI detection tools are our cobra bounty. They were supposed to reduce AI use. Instead, they’re incentivizing it.</p><p>And this goes well beyond one student’s experience. Maye describes a pattern spreading across his classrooms:</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>One student, a native English speaker, had long been praised for writing above grade level. This semester, a transfer to a new college brought a new concern. Professors unfamiliar with her work would have no way of knowing that her confident voice had been earned. She turned to Google Gemini with a pointed inquiry about what raises red flags for college instructors. That inquiry opened a door. She learned how prompts shape outputs, when certain sentence patterns attract scrutiny, and ways in which stylistic confidence trigger doubt. The tool became a way to supplement coursework and clarify difficult material. Still, the practice felt wrong. “I feel like I’m cheating,” she told me, although the impulse that led her there had been defensive.</em></p>
</blockquote><p>A student praised for years for being an exceptional writer now feels like a cheater because she had to learn how AI detection works in order to protect herself from being falsely accused. The surveillance apparatus has turned writing talent into a liability.</p><p>Then there’s this:</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>After being accused of using AI in a different course, another student came to me. The accusation was unfounded, yet the paper went ungraded. What followed unsettled me. “I feel like I have to stay abreast of the technology that placed me in that situation,” the student said, “so I can protect myself from it.” Protection took the form of immersion. Multiple AI subscriptions. Careful study of how detection works. A fluency in tools the student had never planned to use. The experience ended with a decision. Other professors would not be informed. “I don’t believe they will view me favorably.”</em></p>
</blockquote><p>The false accusation resulted in the student <em>subscribing to multiple AI services</em> and studying how the detection systems work. Not because they wanted to cheat, but because they felt they had no other option for self-defense. And then they decided to keep quiet about it, because telling professors about their AI literacy would only invite more suspicion.</p><p>Look, I get it: some students <em>are absolutely</em> using AI to cheat, and that’s a real issue educators have to deal with. But the detection-first approach has created an incentive structure that’s almost perfectly backwards. Students who don’t use AI are punished for writing too well. Students who are falsely accused learn that the only defense is to become fluent in the very tools they’re accused of using. And the students savvy enough to actually cheat? They’re the ones best equipped to game the detectors. The tools aren’t catching the cheaters—they’re radicalizing the honest kids.</p><p>As Maye explains, this dynamic is especially brutal at open-access institutions like CUNY, where students already face enormous pressures:</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>At CUNY, many students work 20 to 40 hours a week. Many are multilingual. They encounter a different AI policy in nearly every course. When one professor bans AI entirely and another encourages its use, students learn to stay quiet rather than risk a misstep. The burden of inconsistency falls on them, and it takes a concrete form: time, revision, and self-surveillance. One student described spending hours rephrasing sentences that detectors flagged as AI-generated even though every word was original. “I revise and revise,” the student said. “It takes too much time.”</em></p>
</blockquote><p>Just like my kid and the school-provided AI checker, Maye’s student spent a bunch of wasted time “revising” to avoid being flagged.</p><p>Students spending hours rewriting their own original work—work that <em>they</em> wrote—because an algorithm decided it sounded too much like a machine. That’s time taken away from studying, working, caring for family, or, you know, actually learning to write better.</p><p>Learning to revise is a key part of learning to write. But revisions should be done to serve the intent of the writing. Not to appease a sketchy bot checker.</p><p>What Maye articulates so well is that the damage here goes beyond false positives and wasted time. The deeper problem is what these tools <em>teach</em> students about writing:</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Detection tools communicate, even when instructors do not, that writing is a performance to be managed rather than a practice to be developed. Students learn that style can count against them, and that fluency invites suspicion.</em></p>
</blockquote><p>We are teaching an entire generation of students that the goal of writing is to sound sufficiently unremarkable! Not to express an original thought, develop an argument, find your voice, or communicate with clarity and power—but to produce text bland enough that a statistical model doesn’t flag it.</p><p>The word “devoid” is too risky. Em dashes are suspicious. Confident prose is a red flag.</p><p>My kid’s <em>Harrison Bergeron</em> experience was, in retrospect, a perfect preview of all of this. Vonnegut warned about a society that forces everyone down to the lowest common denominator by handicapping anyone who shows ability. And here we are, with AI detection tools functioning as the Handicapper General of student writing, punishing fluency, penalizing vocabulary, and training students to sound as mediocre as possible to avoid triggering an algorithm that can’t even tell the difference between a thoughtful essay and a ChatGPT output.</p><p>Maye eventually did the only sensible thing: he stopped playing the game.</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Midway through the semester, I stopped requiring students to disclose their AI use. My syllabi had asked for transparency, yet the expectation had become incoherent. The boundary between using AI and navigating the internet had blurred beyond recognition. Asking students to document every encounter with the technology would have turned writing into an accounting exercise. I shifted my approach. I told students they could use AI for research and outlining, while drafting had to remain their own. I taught them how to prompt responsibly and how to recognize when a tool began replacing their thinking.</em></p>
</blockquote><p>Rather than taking a “guilt-first” approach, he took one that dealt with reality and focused on what would actually be best for the learning environment: teach students to use the tools appropriately, not as a shortcut, and don’t start from a position of suspicion.</p><blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>The atmosphere in my classroom changed. Students approached me after class to ask how to use these tools well. One wanted to know how to prompt for research without copying output. Another asked how to tell when a summary drifted too far from its source.</em> <strong><em>These conversations were pedagogical in nature</em></strong><em>. They became possible only after AI use stopped functioning as a disclosure problem and began functioning as a subject of instruction.</em></p>
</blockquote><p>Once the surveillance regime was lifted, students could actually <em>learn</em>. They asked genuine questions about how to use tools effectively and ethically. They engaged with the technology as a subject worth understanding rather than a minefield to navigate. The teacher-student relationship shifted from adversarial to educational, which is, you know, kind of the whole point of school.</p><p>That line Maye uses: “these conversations were pedagogical in nature” keeps sticking in my brain. The fear of AI undermining teaching made it impossible to teach. Getting past that fear brought back the pedagogy. Incredible.</p><p>This piece should be required reading for every educator thinking that “catching” students using AI is the most important thing.</p><p>As Maye discovered through painful experience, the answer is to stop treating AI as a policing problem and start treating it as an educational one. Teach students how to write. Teach them how to think critically about AI tools. Teach them when those tools are helpful, when they’re harmful, and when they’re a crutch. And for the love of all that is good, stop deploying detection tools that punish good writers and push everyone toward a bland, algorithmic mean.</p><p>We are, quite literally, limiting our students’ writing to satisfy a machine that can’t tell the difference. Vonnegut would have had a field day.</p><p class="filed">Filed Under: <a href="https://www.techdirt.com/tag/ai/" rel="tag">ai</a>, <a href="https://www.techdirt.com/tag/ai-detection/" rel="tag">ai detection</a>, <a href="https://www.techdirt.com/tag/cheating/" rel="tag">cheating</a>, <a href="https://www.techdirt.com/tag/dadland-maye/" rel="tag">dadland maye</a>, <a href="https://www.techdirt.com/tag/students/" rel="tag">students</a><br /></p>]]></description>
      <link>https://www.techdirt.com/2026/03/06/were-training-students-to-write-worse-to-prove-theyre-not-robots-and-its-pushing-them-to-use-more-ai/</link>
      <guid>https://www.techdirt.com/2026/03/06/were-training-students-to-write-worse-to-prove-theyre-not-robots-and-its-pushing-them-to-use-more-ai/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Defuddle — Get the main content of any page as Markdown.]]></title>
      <description><![CDATA[]]></description>
      <link>https://defuddle.md/</link>
      <guid>https://defuddle.md/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Labor market impacts of AI: A new measure and early evidence Anthropic]]></title>
      <description><![CDATA[<h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="key-findings">Key Findings</h2><ul class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text"><li>We introduce a new measure of AI displacement risk, <em>observed exposure</em>, that combines theoretical LLM capability and real-world usage data, weighting automated (rather than augmentative) and work-related uses more heavily</li>
<li>AI is far from reaching its theoretical capability: actual coverage remains a fraction of what's feasible</li>
<li>Occupations with higher observed exposure are projected by the BLS to grow less through 2034</li>
<li>Workers in the most exposed professions are more likely to be older, female, more educated, and higher-paid</li>
<li>We find no systematic increase in unemployment for highly exposed workers since late 2022, though we find suggestive evidence that hiring of younger workers has slowed in exposed occupations</li>
</ul><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="introduction">Introduction</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">The rapid diffusion of AI is generating a wave of research measuring and forecasting its impacts on labor markets. But the track record of past approaches gives reason for humility.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">For example, a prominent attempt to measure job offshorability identified roughly a quarter of US jobs as vulnerable, but a decade on, most of those jobs maintained healthy employment growth. The government’s own occupational growth forecasts, while directionally correct, have added little predictive value beyond linear extrapolation of past trends. Even in hindsight, the impact of major economic disruptions on the labor market is often unclear. Studies on the employment effects of industrial robots reach opposing conclusions, and the scale of job losses attributed to the China trade shock continues to be debated.<sup class="caption Body-module-scss-module__z40yvW__sup">1</sup></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">In this paper, we present a new framework for understanding AI’s labor market impacts, and test it against early data, finding limited evidence that AI has affected employment to date. Our goal is to establish an approach for measuring how AI is affecting employment, and to revisit these analyses periodically. This approach won't capture every channel through which AI could reshape the labor market, but by laying this groundwork now, before meaningful effects have emerged, we hope future findings will more reliably identify economic disruption than post-hoc analyses.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">It is possible that the impacts of AI will be unmistakable. This framework is most useful when the effects are ambiguous—and could help identify the most vulnerable jobs before displacement is visible.</p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="counterfactuals-"><br />Counterfactuals</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Causal inference is easier when the effects are large and sudden. The COVID-19 pandemic and accompanying policy measures caused economic disruption so stark that sophisticated statistical approaches were unnecessary for many questions. For example, unemployment jumped sharply in the early weeks of the pandemic, leaving little room for alternative explanations.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">The impacts of AI, however, might be less like COVID and more like the internet or trade with China. The effects may not be immediately clear from aggregate unemployment data; factors like trade policy and the business cycle could cloud interpretations of trend lines.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">One common approach is to compare outcomes between more or less AI-exposed workers, firms, or industries, in order to isolate the effect of AI from confounding forces.<sup class="caption Body-module-scss-module__z40yvW__sup">2</sup> Exposure is typically defined at the task level: AI can grade homework but not manage a classroom, for example, so teachers are considered less exposed than workers whose entire job can be performed remotely.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Our work follows this task-based approach, incorporating measures of theoretical AI capability and real-world usage, before aggregating to occupations.<sup class="caption Body-module-scss-module__z40yvW__sup">3</sup></p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="measuring-exposure-">Measuring exposure</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Our approach combines data from three sources.</p><ol class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text"><li>The <a href="https://www.onetcenter.org/database.html" target="_blank" rel="noopener noreferrer">O*NET database</a>, which enumerates tasks associated with around 800 unique occupations in the US.</li>
<li>Our own usage data (as measured in the <a href="https://www.anthropic.com/economic-index" target="_blank" rel="noopener noreferrer">Anthropic Economic Index</a>).</li>
<li>Task-level exposure estimates from Eloundou et al. (2023), which measure whether it is theoretically possible for an LLM to make a task at least twice as fast.</li>
</ol><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Eloundou et al.’s metric, β, scores tasks on a simple scale: 1 if a task can be doubled in speed by an LLM alone, 0.5 if it requires additional tools or software built on top of the LLM, and 0 otherwise.<sup class="caption Body-module-scss-module__z40yvW__sup">4</sup></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Why might actual usage fall short of theoretical capability? Some tasks that are theoretically possible may not show up in usage because of model limitations. Others may be slow to diffuse due to legal constraints, specific software requirements, human verification steps, or other hurdles. For example, Eloundou et al. mark “Authorize drug refills and provide prescription information to pharmacies” as fully exposed (β=1). We have not observed Claude performing this task, although the assessment seems correct in that it could theoretically be sped up by an LLM.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">That said, these measures of theoretical capability and actual usage are highly correlated. As Figure 1 shows, 97% of the tasks observed across the previous four Economic Index reports fall into categories rated as theoretically feasible by Eloundou et al. (β=0.5 or β=1.0).</p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4584" height="2579" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2F9d205667455ef8b78e8cbb407b6bd76556a7d859-4584x2579.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2F9d205667455ef8b78e8cbb407b6bd76556a7d859-4584x2579.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 1: Share of Claude usage by Eloundou et al. task exposure rating<br /></strong>This figure shows Claude usage distributed across O*NET tasks grouped by their theoretical AI exposure. Tasks rated β=1 (fully feasible for an LLM alone) account for 68% of observed Claude usage, while tasks rated β=0 (not feasible) account for just 3%. Data on Claude usage comes from the previous four Economic Index reports.</figcaption></figure></div><h3 class="Body-module-scss-module__z40yvW__reading-column headline-6 post-subsection" id="a-new-measure-of-occupational-exposure-"><br />A new measure of occupational exposure</h3><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Our new measure, <em>observed exposure</em>, is meant to quantify: of those tasks that LLMs could theoretically speed up, which are actually seeing automated usage in professional settings? Theoretical capability encompasses a much broader range of tasks. By tracking how that gap narrows, observed exposure provides insight into economic changes as they emerge.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Our measure qualitatively captures several aspects of AI usage that we think are predictive of job impacts. A job's exposure is higher if:</p><ul class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text"><li>Its tasks are theoretically possible with AI</li>
<li>Its tasks see significant usage in the Anthropic Economic Index<sup class="caption Body-module-scss-module__z40yvW__sup">5</sup></li>
<li>Its tasks are performed in work-related contexts</li>
<li>It has a relatively higher share of automated use patterns or API implementation</li>
<li>Its AI-impacted tasks make up a larger share of the overall role<sup class="caption Body-module-scss-module__z40yvW__sup">6</sup></li>
</ul><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">We give mathematical details in the <a href="https://cdn.sanity.io/files/4zrzovbb/website/e5f77fc0e77c0185110b5e4b909602791ae76eae.pdf" target="_blank" rel="noopener noreferrer">Appendix</a>. We count tasks that are theoretically capable with an LLM as covered if they have seen sufficient work-related usage in Claude traffic. We then adjust for how the task is being carried out: fully automated implementations receive full weight, while augmentative use receives half weight. Finally, the task-level coverage measures are averaged to the occupation level weighted by the fraction of time spent on each task.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Figure 2 shows observed exposure (in red) compared to β from Eloundou et al. (in blue), illustrating the difference between theoretical and actual use on our platform, grouped by broad occupational categories. We calculate this by first averaging to the occupation level weighting by our time fraction measure, then averaging to the occupation category weighting by total employment. For example, the β measure shows scope for LLM penetration in the majority of tasks in Computer &amp; Math (94%) and Office &amp; Admin (90%) occupations.</p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4096" height="4096" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fc1952c81bca02a7c8cc05ef7801e67ca60831c55-4096x4096.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fc1952c81bca02a7c8cc05ef7801e67ca60831c55-4096x4096.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 2: Theoretical capability and observed exposure by occupational category<br /></strong>Share of job tasks that LLMs could theoretically perform (blue area) and our own job coverage measure derived from usage data (red area).</figcaption></figure></div><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">The red area, depicting LLM use from the Anthropic Economic Index, shows how people are using Claude in professional settings. The coverage shows AI is far from reaching its theoretical capabilities. For instance, Claude currently covers just 33% of all tasks in the Computer &amp; Math category.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">As capabilities advance, adoption spreads, and deployment deepens, the red area will grow to cover the blue. There is a large uncovered area too; many tasks, of course, remain beyond AI's reach—from physical agricultural work like pruning trees and operating farm machinery to legal tasks like representing clients in court.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Figure 3 shows the ten occupations most exposed under this measure. In line with other data showing that Claude is extensively used for coding, Computer Programmers are at the top, with 75% coverage, followed by Customer Service Representatives, whose main tasks we increasingly see in first-party API traffic. Finally, Data Entry Keyers, whose primary task of reading source documents and entering data sees significant automation, are 67% covered.</p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4584" height="2579" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fa16a5b9ba4a5280ef41e058dff6964a3f116c854-4584x2579.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fa16a5b9ba4a5280ef41e058dff6964a3f116c854-4584x2579.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 3: Most exposed occupations</strong>Top ten most exposed occupations using our task coverage measure.<br /></figcaption></figure></div><p>At the bottom end, 30% of workers have zero coverage, as their tasks appeared too infrequently in our data to meet the minimum threshold. This group includes, for example, Cooks, Motorcycle Mechanics, Lifeguards, Bartenders, Dishwashers, and Dressing Room Attendants.</p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="how-exposure-tracks-with-projected-job-growth-and-worker-characteristics"><strong>How exposure tracks with projected job growth and worker characteristics</strong></h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">The US Bureau of Labor Statistics (BLS) publishes regular employment projections, with the latest set, published in 2025, covering <a href="https://data.bls.gov/projections/occupationProj" target="_blank" rel="noopener noreferrer">predicted</a> changes in employment for every occupation from 2024 to 2034. In Figure 4, we compare our job-level coverage measure to their predictions.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">A regression at the occupation level weighted by current employment finds that growth projections are somewhat weaker for jobs with more observed exposure. For every 10 percentage point increase in coverage, the BLS’s growth projection drops by 0.6 percentage points. This provides some validation in that our measures track the independently derived estimates from labor market analysts, although the relationship is slight. Interestingly, there is no such correlation using the Eloundou et al. measure alone.</p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4584" height="2579" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2F4da91f7eeb62c2c7b09600282c9163f6bdf0d5ca-4584x2579.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2F4da91f7eeb62c2c7b09600282c9163f6bdf0d5ca-4584x2579.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 4: BLS projected employment growth from 2024—2034 vs. observed exposure<br /></strong>Binned scatterplot with 25 equally-sized bins. Each solid dot shows the average observed exposure and projected employment change for one of the bins. The dashed line shows a simple linear regression fit, weighted by current employment levels. The small diamonds mark individual example occupations for illustration.<br /></figcaption></figure></div><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Figure 5 shows characteristics of workers in the top quartile of exposure and the 30% of workers with zero exposure in the three months before ChatGPT was released, August to October 2022, using data from the Current Population Survey.<sup class="caption Body-module-scss-module__z40yvW__sup">7</sup> The groups are very different. The more exposed group is 16 percentage points more likely to be female, 11 percentage points more likely to be white, and almost twice as likely to be Asian. They earn 47% more, on average, and have higher levels of education. For example, people with graduate degrees are 4.5% of the unexposed group, but 17.4% of the most exposed group, an almost fourfold difference.</p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4584" height="2579" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fff251060d019f4fdf6579df08aaf61e94b4c2d27-4584x2579.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fff251060d019f4fdf6579df08aaf61e94b4c2d27-4584x2579.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 5: Differences between high and low exposure workers, Current Population Survey</strong></figcaption></figure></div><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="prioritizing-outcomes">Prioritizing outcomes</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">With these exposure measures in hand, the question is what to look for. Researchers have taken different approaches. For example, Gimbel et al. (2025) track changes in the occupational mix using the Current Population Survey. Their argument is that any important restructuring of the economy from AI would show up as changes in distribution of jobs.¹ (They find that, so far, changes have been unremarkable.) Brynjolfsson et al. (2025) look at employment levels split by age group using data from the payroll processing firm ADP, while Acemoglu et al. (2022) and Hampole et al. (2025) use job posting data from Burning Glass (now Lightcast) and Revelio, respectively.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">We focus on unemployment as our priority outcome because it most directly captures the potential for economic harm—a worker who is unemployed wants a job and has not yet found one. In this case, job postings and employment do not necessarily signal the need for policy responses; a decline in job postings for a highly exposed role may be counteracted by increased openings in a related one. Most harmful labor market developments of AI should arguably include a period of increased unemployment, as displaced workers search for alternatives. The Current Population Survey is well suited to tracking this, as unemployed respondents report their previous job and industry.</p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="initial-results"><br />Initial results<br /></h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">We next study trends in unemployment, matching our occupation-level measures to respondents in the Current Population Survey.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">A key question in interpreting our coverage measure is which workers should be considered treated? Should changes in employment be expected from just 10% task coverage? Gans and Goldfarb (2025) show that if an O-ring model best describes jobs, employment effects might be seen only when all tasks have some degree of AI penetration. Hampole et al. (2025) argue that mean exposure decreases labor demand, but <em>concentration</em> of exposure in only certain tasks can counteract this. And Autor and Thompson (2025) highlight the level of expertise required for the remaining tasks.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">With an eye toward simplicity, and noting that we are most concerned with large impacts, we center our analysis on the idea that impacts should be felt most in the groups with the highest mean exposure. We compare workers in the top quartile of time-weighted task coverage to those in the bottom. If AI capabilities advance quickly, task coverage might be high for lower percentiles of coverage, which might make an absolute threshold more helpful. But we make the assumption that impacts should affect the most exposed workers first, and present results varying the cutoff we use to define treatment.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">The upper panel of Figure 6 shows raw trends in the unemployment rate since 2016 for workers in the top quartile of exposure and the unexposed group. During COVID, the less AI-exposed workers—who are more likely to have in-person jobs—saw a much larger increase in unemployment. Since then, the trends have been largely similar between the two groups. The lower panel measures the size of the gap between the most and least exposed workers in a difference-in-differences framework, mirroring the findings from the raw data. The average change in the gap since the release of ChatGPT is small and insignificant, suggesting that the unemployment rate of the more exposed group has increased slightly but the effect is indistinguishable from zero.<sup class="caption Body-module-scss-module__z40yvW__sup">8</sup></p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4584" height="2579" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fe4cf7bf0364758fe1bfbb7b915c8f1db6d7bd4d4-4584x2579.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2Fe4cf7bf0364758fe1bfbb7b915c8f1db6d7bd4d4-4584x2579.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 6: Trends in the unemployment rate for workers in the top quartile of observed exposure and no AI exposure, Current Population Survey<br /></strong>The top panel shows the unemployment rate for workers in the top quartile of exposure (red line) and the 30% of workers with zero exposure. The bottom panel measures the gap between these two series in a difference-in-differences framework.<br /></figcaption></figure></div><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text"><strong><br /></strong>What kind of scenarios can this framework identify? Based on the confidence interval of the pooled estimate, differential increases in unemployment on the order of 1 percentage point would be detectable (this will change as new data comes in, so it is merely a ballpark estimate). If all workers within the top 10% were laid off, it would increase unemployment within the top quartile group from 3% to 43%, and it would increase aggregate unemployment from 4% to 13%.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">A smaller but still concerning impact would be a scenario such as a “Great Recession for white-collar workers.” During the 2007-2009 Great Recession, unemployment rates doubled from 5% to 10% in the US. Such a doubling in the top quartile of exposure would increase its unemployment rate from 3% to 6%. This should be visible in our analysis as well. Note that our core estimate is based on <em>differential</em> changes in the unemployment rate in the exposed group compared to the less exposed group. If unemployment increased for all workers in parallel, we would not attribute this to AI advancements that still leave many tasks unaffected.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">One group of particular concern is young workers. Brynjolfsson et al. report a 6—16% fall in employment in exposed occupations among workers aged 22 to 25. They attribute this decrease primarily to a slowdown in hiring rather than an increase in separations.<sup class="caption Body-module-scss-module__z40yvW__sup">9</sup></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">We find that the unemployment rate for young workers in the exposed occupations is flat (see <a href="https://cdn.sanity.io/files/4zrzovbb/website/e5f77fc0e77c0185110b5e4b909602791ae76eae.pdf" target="_blank" rel="noopener noreferrer">Appendix</a>). But slowed hiring may not necessarily manifest as increased unemployment, since many young workers are labor market entrants without a listed occupation in the CPS data and may exit the labor force rather than appear as unemployed. To address hiring directly, we use the panel dimension of the CPS, counting the percent of young (22-25 year old) workers who begin a new job in a more vs. less exposed occupation over time. Figure 7 shows the monthly job finding rate (i.e., when a worker reports a job that they did not have in the previous month) for young workers, split by whether they are entering a high- vs. low-exposure occupation.</p><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline"><figure class="ImageWithCaption-module-scss-module__Duq99q__e-imageWithCaption"><img width="4584" height="2579" data-nimg="1" class="c1" srcset="/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2F1e4020e4312e8eeb4601f542a96cb238234f6c8b-4584x2579.png&amp;w=3840&amp;q=75 1x" src="https://www.anthropic.com/_next/image?url=https%3A%2F%2Fwww-cdn.anthropic.com%2Fimages%2F4zrzovbb%2Fwebsite%2F1e4020e4312e8eeb4601f542a96cb238234f6c8b-4584x2579.png&amp;w=3840&amp;q=75" alt="image" /><figcaption class="caption"><strong>Figure 7: New job starts among workers age 22-25 in occupations with high observed exposure and no AI exposure, Current Population Survey<br /></strong>The top panel shows the percent of young workers starting new jobs in high vs. no exposure occupations. The bottom panel measures the gap between these two series in a difference-in-differences framework.<br /></figcaption></figure></div><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Apart from some large swings in 2020-2021, these series visually diverge in 2024, with young workers relatively less likely to be hired into exposed occupations. Job finding rates at the less exposed occupations remain stable at 2% per month, while entry into the most exposed jobs decreases by about half a percentage point. The averaged estimate in the post-ChatGPT era is a 14% drop in the job finding rate compared to that in 2022 in the exposed occupations, although this is just barely statistically significant. (There is no such decrease for workers older than 25.)</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">This may provide some signal of the early effects of AI on employment, and echoes the findings from Brynjolfsson et al. But there are several alternative interpretations. The young workers who are not hired may be remaining at their existing jobs, taking different jobs, or returning to school. A further data-related caveat is that job transitions may be more vulnerable to mismeasurement in surveys.<sup class="caption Body-module-scss-module__z40yvW__sup">10</sup><br /></p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="discussion"><br />Discussion</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">This report introduces a new measure for understanding the labor market effects of AI and studies impacts on unemployment and hiring. Jobs are more exposed to AI to the extent that their tasks are theoretically feasible with LLMs and observed on our platforms in automated, work-related use cases. We find that computer programmers, customer service representatives, and financial analysts are among the most exposed. Using survey data from the US, we find no impact on unemployment rates for workers in the most exposed occupations, although there’s tentative evidence that hiring into those professions has slowed slightly for workers aged 22-25.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Our work is a first step toward cataloging the impact of AI on the labor market. We hope that the analytical steps taken in this report, especially around coverage and counterfactuals, will be easy to update as new data on employment and AI usage emerge. An established approach may help future observers separate signal from noise.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">There are several improvements to be made to the present work. Our usage data will be incorporated in future updates, forming an evolving picture of task and job coverage in the economy. The Eloundou et al. metric could also be updated, to the extent that it is linked to LLM capabilities as of early 2023. And, given the suggestive results around young workers and labor market entrants, a key next step might be to look at how recent graduates with educational credentials in exposed areas are navigating the labor market.</p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="appendix">Appendix</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Available <a href="https://cdn.sanity.io/files/4zrzovbb/website/e5f77fc0e77c0185110b5e4b909602791ae76eae.pdf" target="_blank" rel="noopener noreferrer">here.</a><br /></p><h3 class="Body-module-scss-module__z40yvW__reading-column headline-6 post-subsection" id="acknowledgements"><br />Acknowledgements</h3><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Written by Maxim Massenkoff and Peter McCrory.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">With acknowledgements to: Ruth Appel, Tim Belonax, Keir Bradwell, Andy Braden, Dexter Callender III, Miriam Chaum, Madison Clark, Jake Eaton, Deep Ganguli, Kunal Handa, Ryan Heller, Lara Karadogan, Jennifer Martinez, Jared Mueller, Sarah Pollack, David Saunders, Carl De Torres, Kim Withee, and Jack Clark.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">We additionally thank Martha Gimbel, Anders Humlum, Evan Rose, and Nathan Wilmers for feedback on earlier versions of this report.</p><h3 class="Body-module-scss-module__z40yvW__reading-column headline-6 post-subsection" id="citation"><br />Citation</h3><div class="Body-module-scss-module__z40yvW__media-column Body-module-scss-module__z40yvW__inline CodeBlock-module-scss-module__PbWBnq__codeBlock"><pre class="plaintext">@online{massenkoffmccrory2026labor,
 author = {Maxim Massenkoff and Peter McCrory},
 title = {Labor market impacts of AI: A new measure and early evidence},
 date = {2026-03-05},
 year = {2026},
 url = {https://www.anthropic.com/research/labor-market-impacts},
}</pre></div><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="references-">References</h2><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Acemoglu, Daron and Pascual Restrepo, "Robots and Jobs: Evidence from US Labor Markets," <em>Journal of Political Economy</em>, 2020, 128 (6), 2188–2244.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Acemoglu, Daron, David Autor, Jonathon Hazell, and Pascual Restrepo, "Artificial intelligence and jobs: Evidence from online vacancies," <em>Journal of Labor Economics</em>, 2022, 40 (S1), S293–S340.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Appel, Ruth, Maxim Massenkoff, Peter McCrory, Miles McCain, Ryan Heller, Tyler Neylon, and Alex Tamkin, "Anthropic Economic Index report: economic primitives," 2026.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Autor, David H, David Dorn, and Gordon H Hanson, "The China syndrome: Local labor market effects of import competition in the United States," <em>American Economic Review</em>, 2013, 103 (6), 2121–2168.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Autor, David H, &amp; Thompson, N. (2025). Expertise. NBER Working Paper, (w33941).</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Blinder, Alan S et al., "How many US jobs might be offshorable?," <em>World Economics</em>, 2009, 10 (2), 41.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Borusyak, Kirill, Peter Hull, and Xavier Jaravel, "Quasi-experimental shift-share research designs," <em>The Review of Economic Studies</em>, 2022, 89 (1), 181–213.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Brynjolfsson, Erik, Bharat Chandar, and Ruyu Chen, "Canaries in the coal mine? six facts about the recent employment effects of artificial intelligence," <em>Digital Economy</em>, 2025.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Eckhardt, Sarah and Nathan Goldschlag, "AI and Jobs: The Final Word (Until the Next One)," Economic Innovation Group (EIG), August 2025. Available at: <a href="https://eig.org/ai-and-jobs-the-final-word/">https://eig.org/ai-and-jobs-the-final-word/</a></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Eloundou, Tyna, Sam Manning, Pamela Mishkin, and Daniel Rock, "Gpts are gpts: An early look at the labor market impact potential of large language models," arXiv preprint arXiv:2303.10130, 2023, 10.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Fujita, S., Moscarini, G., &amp; Postel-Vinay, F. (2024). Measuring employer-to-employer reallocation. <em>American Economic Journal: Macroeconomics</em>, 16(3), 1-51.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Gans, Joshua S. and Goldfarb, Avi, "O-Ring Automation," NBER Working Paper No. 34639, December 2025. Available at SSRN: <a href="https://ssrn.com/abstract=5962594">https://ssrn.com/abstract=5962594</a></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Gimbel, Martha, Molly Kinder, Joshua Kendall, and Maddie Lee, "Evaluating the Impact of AI on the Labor Market: Current State of Affairs," Research Report, The Budget Lab at Yale, New Haven, CT October 2025. Available at: <a href="https://budgetlab.yale.edu">https://budgetlab.yale.edu</a>.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Graetz, Georg and Guy Michaels, "Robots at Work," <em>Review of Economics and Statistics</em>, 2018, 100 (5), 753–768.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Hampole, Menaka, Dimitris Papanikolaou, Lawrence DW Schmidt, and Bryan Seegmiller, "Artificial intelligence and the labor market," Technical Report, National Bureau of Economic Research 2025.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Handa, Kunal, Alex Tamkin, Miles McCain, Saffron Huang, Esin Durmus, Sarah Heck, Jared Mueller, Jerry Hong, Stuart Ritchie, Tim Belonax, Kevin K. Troy, Dario Amodei, Jared Kaplan, Jack Clark, and Deep Ganguli, "Which Economic Tasks are Performed with AI? Evidence from Millions of Claude Conversations," 2025.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Hui, Xiang, Oren Reshef, and Luofeng Zhou, "The short-term effects of generative artificial intelligence on employment: Evidence from an online labor market," <em>Organization Science</em>, 2024, 35 (6), 1977–1989.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Johnston, Andrew and Christos Makridis, "The labor market effects of generative AI: A difference-in-differences analysis of AI exposure," Available at SSRN 5375017, 2025.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Massenkoff, Maxim, "How predictable is job destruction? Evidence from the Occupational Outlook," 2025. <em>Working Paper.</em></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Ozimek, Adam, "Overboard on Offshore Fears," 2019. <a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3777307">https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3777307</a></p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Tamkin, Alex and Peter McCrory, "Estimating AI productivity gains from Claude conversations," 2025.</p><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text">Tomlinson, K., Jaffe, S., Wang, W., Counts, S., &amp; Suri, S. (2025). Working with AI: measuring the applicability of generative AI to occupations. arXiv preprint arXiv:2507.07935.</p><h2 class="Body-module-scss-module__z40yvW__reading-column headline-5 post-section" id="footnotes"><br />Footnotes</h2><ol class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text"><li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">Job offshorability: Blinder et al. (2009) and Ozimek (2019); Government growth forecasts: Massenkoff (2025); Robots: Graetz and Michaels (2018) and Acemoglu and Restrepo (2020); China shock: Autor et al. (2013) and Borusyak et al. (2022).</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">Brynjolfsson et al. (2025) compare employment trends for workers in more versus less AI-exposed occupations, using the task exposure measures from Eloundou et al. (2023) and payroll data from ADP. Johnston and Makridis (2025) do a similar task-based analysis using US administrative data, but they aggregate treatment to the industry level. Hui et al. (2024) study how freelance jobs on Upwork responded to the release of ChatGPT and advanced image generation tools, comparing workers in directly affected categories to those in unaffected categories before and after each tool's release date. Hampole et al. (2025) instrument for firm-level AI adoption using historical university hiring networks: firms that historically recruited from universities whose graduates later entered AI-related roles faced lower adoption costs.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">Our task- and occupation-level exposure measures can readily incorporate other usage data, and be extended to different countries. We intend to apply this methodology to new settings over time.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">In their framework, “Directly exposed'” tasks were those that could be completed in half the time with an LLM (with a 2,000-word input limit and no access to recent facts). Tasks that were “exposed with tools” were those subject to the same speedup with an LLM that had access to software for, e.g., information retrieval and image processing. Tasks that were not exposed could not have their duration reduced by 50% or more using an LLM.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">We use the previous two Anthropic Economic Index datasets, covering usage from August and November 2025. For ONET tasks that are highly semantically similar, we split the counts across them.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">There are judgment calls involved at every step. Should the Eloundou et al. (2023) measure enter as {0, 0.5, 1} or something else? What determines "significant" use? How do we handle tasks which seem very similar to those with high usage, but are too rare to have been picked up specifically in the sampling for the Economic Index? How much more should automation workflows count compared to augmentation? A reassuring finding which we expand on in the Appendix is that the Spearman (rank-rank) correlation of job exposure across many resolutions to these questions is exceedingly high.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">To match O*NET-SOC codes to occ1990 codes in the CPS, we use the crosswalk provided by <a href="https://eig.org/ai-and-jobs-the-final-word/">Eckhart and Goldschlag (2025)</a>.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">We explore this further in three ways in the <a href="https://cdn.sanity.io/files/4zrzovbb/website/e5f77fc0e77c0185110b5e4b909602791ae76eae.pdf">Appendix</a>. First, we ask whether the percentile cutoff that we use to define treatment matters, varying it from the median to the 95th percentile. In all cases, the impact is flat or negative (meaning that unemployment decreases for the exposed group). Next, we focus on young workers in particular, those aged 22 to 25 as in Brynjolfsson et al. (2025). Finally, we use data on unemployment insurance claimants from the Department of Labor to measure the unemployment, rather than CPS survey responses. In no extension do we find clear impacts on exposed jobs.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">This range is wide because the authors provide estimates against multiple counterfactuals. The 6 percentage point drop compares to a counterfactual of flat employment growth. The 16 percentage point estimate comes from a design comparing similar workers in the same firm with different occupations.</p>
</li>
<li>
<p class="Body-module-scss-module__z40yvW__reading-column body-3 serif post-footnote Body-module-scss-module__z40yvW__footnote">See Fujita, et al. (2024).</p>
</li>
</ol><h3 class="Body-module-scss-module__z40yvW__reading-column headline-6 post-subsection" id="corrections">Corrections</h3><p class="Body-module-scss-module__z40yvW__reading-column body-2 serif post-text"><em>Updated Mar 8, 2026: Corrected Figure 7, which incorrectly reversed the labels between top quartile and zero exposure group inflow rates.</em><br /></p>]]></description>
      <link>https://www.anthropic.com/research/labor-market-impacts</link>
      <guid>https://www.anthropic.com/research/labor-market-impacts</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[googleworkspace/cli: Google Workspace CLI — one command-line tool for Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin, and more. Dynamically built from Google Discovery Service. Includes AI agent skills.]]></title>
      <description><![CDATA[<div id="readme" class="md" data-path="README.md"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 align="center" class="heading-element" dir="auto">gws</h1><a id="user-content-gws" class="anchor" aria-label="Permalink: gws" href="#gws"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>One CLI for all of Google Workspace — built for humans and AI agents.</strong><br>
Drive, Gmail, Calendar, and every Workspace API. Zero boilerplate. Structured JSON output. 40+ agent skills included.</p>
<div class="markdown-alert markdown-alert-note" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-info mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Note</p><p dir="auto">This is <strong>not</strong> an officially supported Google product.</p>
</div>
<p dir="auto">
  <a href="https://www.npmjs.com/package/@googleworkspace/cli" rel="nofollow"><img src="https://camo.githubusercontent.com/4853e953516d5f164a9f4f700d7685fc8029cb9193ba11a7f133dd1be9944cc5/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f40676f6f676c65776f726b73706163652f636c69" alt="npm version" data-canonical-src="https://img.shields.io/npm/v/@googleworkspace/cli" style="max-width: 100%;"></a>
  <a href="https://github.com/googleworkspace/cli/blob/main/LICENSE"><img src="https://camo.githubusercontent.com/7ae38d1c7e56b6b45bfd15bca0e93945abdd5b3bafab93771df6da4025024eaa/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f676f6f676c65776f726b73706163652f636c69" alt="license" data-canonical-src="https://img.shields.io/github/license/googleworkspace/cli" style="max-width: 100%;"></a>
  <a href="https://github.com/googleworkspace/cli/actions/workflows/ci.yml"><img src="https://camo.githubusercontent.com/32e1c944ab8e80496deee97e80e8d68796a04256690c3fa2ea868b439974905c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f676f6f676c65776f726b73706163652f636c692f63692e796d6c3f6272616e63683d6d61696e266c6162656c3d4349" alt="CI status" data-canonical-src="https://img.shields.io/github/actions/workflow/status/googleworkspace/cli/ci.yml?branch=main&amp;label=CI" style="max-width: 100%;"></a>
  <a href="https://www.npmjs.com/package/@googleworkspace/cli" rel="nofollow"><img src="https://camo.githubusercontent.com/0e0fb92a3d7736795c365b17af022c33ba9dcbce56b8be7fbc487c31cfcbf059/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f756e7061636b65642d73697a652f40676f6f676c65776f726b73706163652f636c69" alt="install size" data-canonical-src="https://img.shields.io/npm/unpacked-size/@googleworkspace/cli" style="max-width: 100%;"></a>
</p>
<br>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="npm install -g @googleworkspace/cli"><pre>npm install -g @googleworkspace/cli</pre></div>
<p dir="auto"><code>gws</code> doesn't ship a static list of commands. It reads Google's own <a href="https://developers.google.com/discovery" rel="nofollow">Discovery Service</a> at runtime and builds its entire command surface dynamically. When Google Workspace adds an API endpoint or method, <code>gws</code> picks it up automatically.</p>
<div class="markdown-alert markdown-alert-important" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-report mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>Important</p><p dir="auto">This project is under active development. Expect breaking changes as we march toward v1.0.</p>
</div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Contents</h2><a id="user-content-contents" class="anchor" aria-label="Permalink: Contents" href="#contents"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#quick-start">Quick Start</a></li>
<li><a href="#why-gws">Why gws?</a></li>
<li><a href="#authentication">Authentication</a></li>
<li><a href="#ai-agent-skills">AI Agent Skills</a></li>
<li><a href="#advanced-usage">Advanced Usage</a></li>
<li><a href="#environment-variables">Environment Variables</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
<li><a href="#development">Development</a></li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Prerequisites</h2><a id="user-content-prerequisites" class="anchor" aria-label="Permalink: Prerequisites" href="#prerequisites"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ul dir="auto">
<li><strong>Node.js 18+</strong> — for <code>npm install</code> (or download a pre-built binary from <a href="https://github.com/googleworkspace/cli/releases">GitHub Releases</a>)</li>
<li><strong>A Google Cloud project</strong> — required for OAuth credentials. You can create one via the <a href="https://console.cloud.google.com/" rel="nofollow">Google Cloud Console</a> or with the <a href="https://cloud.google.com/sdk/docs/install" rel="nofollow"><code>gcloud</code> CLI</a> or with the <code>gws auth setup</code> command.</li>
<li><strong>A Google account</strong> with access to Google Workspace</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Installation</h2><a id="user-content-installation" class="anchor" aria-label="Permalink: Installation" href="#installation"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="npm install -g @googleworkspace/cli"><pre>npm install -g @googleworkspace/cli</pre></div>
<blockquote>
<p dir="auto">The npm package bundles pre-built native binaries for your OS and architecture.
No Rust toolchain required.</p>
</blockquote>
<p dir="auto">Pre-built binaries are also available on the <a href="https://github.com/googleworkspace/cli/releases">GitHub Releases</a> page.</p>
<p dir="auto">Or build from source:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cargo install --git https://github.com/googleworkspace/cli --locked"><pre>cargo install --git https://github.com/googleworkspace/cli --locked</pre></div>
<p dir="auto">A Nix flake is also available at <code>github:googleworkspace/cli</code></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="nix run github:googleworkspace/cli"><pre>nix run github:googleworkspace/cli</pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Quick Start</h2><a id="user-content-quick-start" class="anchor" aria-label="Permalink: Quick Start" href="#quick-start"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth setup     # walks you through Google Cloud project config
gws auth login     # subsequent OAuth login
gws drive files list --params '{&quot;pageSize&quot;: 5}'"><pre>gws auth setup     <span class="pl-c"><span class="pl-c">#</span> walks you through Google Cloud project config</span>
gws auth login     <span class="pl-c"><span class="pl-c">#</span> subsequent OAuth login</span>
gws drive files list --params <span class="pl-s"><span class="pl-pds">'</span>{"pageSize": 5}<span class="pl-pds">'</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Why gws?</h2><a id="user-content-why-gws" class="anchor" aria-label="Permalink: Why gws?" href="#why-gws"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><strong>For humans</strong> — stop writing <code>curl</code> calls against REST docs. <code>gws</code> gives you <code>--help</code> on every resource, <code>--dry-run</code> to preview requests, and auto‑pagination.</p>
<p dir="auto"><strong>For AI agents</strong> — every response is structured JSON. Pair it with the included agent skills and your LLM can manage Workspace without custom tooling.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# List the 10 most recent files
gws drive files list --params '{&quot;pageSize&quot;: 10}'

# Create a spreadsheet
gws sheets spreadsheets create --json '{&quot;properties&quot;: {&quot;title&quot;: &quot;Q1 Budget&quot;}}'

# Send a Chat message
gws chat spaces messages create \
  --params '{&quot;parent&quot;: &quot;spaces/xyz&quot;}' \
  --json '{&quot;text&quot;: &quot;Deploy complete.&quot;}' \
  --dry-run

# Introspect any method's request/response schema
gws schema drive.files.list

# Stream paginated results as NDJSON
gws drive files list --params '{&quot;pageSize&quot;: 100}' --page-all | jq -r '.files[].name'"><pre><span class="pl-c"><span class="pl-c">#</span> List the 10 most recent files</span>
gws drive files list --params <span class="pl-s"><span class="pl-pds">'</span>{"pageSize": 10}<span class="pl-pds">'</span></span>

<span class="pl-c"><span class="pl-c">#</span> Create a spreadsheet</span>
gws sheets spreadsheets create --json <span class="pl-s"><span class="pl-pds">'</span>{"properties": {"title": "Q1 Budget"}}<span class="pl-pds">'</span></span>

<span class="pl-c"><span class="pl-c">#</span> Send a Chat message</span>
gws chat spaces messages create \
  --params <span class="pl-s"><span class="pl-pds">'</span>{"parent": "spaces/xyz"}<span class="pl-pds">'</span></span> \
  --json <span class="pl-s"><span class="pl-pds">'</span>{"text": "Deploy complete."}<span class="pl-pds">'</span></span> \
  --dry-run

<span class="pl-c"><span class="pl-c">#</span> Introspect any method's request/response schema</span>
gws schema drive.files.list

<span class="pl-c"><span class="pl-c">#</span> Stream paginated results as NDJSON</span>
gws drive files list --params <span class="pl-s"><span class="pl-pds">'</span>{"pageSize": 100}<span class="pl-pds">'</span></span> --page-all <span class="pl-k">|</span> jq -r <span class="pl-s"><span class="pl-pds">'</span>.files[].name<span class="pl-pds">'</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Authentication</h2><a id="user-content-authentication" class="anchor" aria-label="Permalink: Authentication" href="#authentication"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The CLI supports multiple auth workflows so it works on your laptop, in CI, and on a server.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Which setup should I use?</h3><a id="user-content-which-setup-should-i-use" class="anchor" aria-label="Permalink: Which setup should I use?" href="#which-setup-should-i-use"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>I have…</th>
<th>Use</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>gcloud</code> installed and authenticated</td>
<td><a href="#interactive-local-desktop"><code>gws auth setup</code></a> (fastest)</td>
</tr>
<tr>
<td>A GCP project but no <code>gcloud</code></td>
<td><a href="#manual-oauth-setup-google-cloud-console">Manual OAuth setup</a></td>
</tr>
<tr>
<td>An existing OAuth access token</td>
<td><a href="#pre-obtained-access-token"><code>GOOGLE_WORKSPACE_CLI_TOKEN</code></a></td>
</tr>
<tr>
<td>Existing Credentials</td>
<td><a href="#service-account-server-to-server"><code>GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE</code></a></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Interactive (local desktop)</h3><a id="user-content-interactive-local-desktop" class="anchor" aria-label="Permalink: Interactive (local desktop)" href="#interactive-local-desktop"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Credentials are encrypted at rest (AES-256-GCM) with the key stored in your OS keyring (or <code>~/.config/gws/.encryption_key</code> when <code>GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=file</code>).</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth setup       # one-time: creates a Cloud project, enables APIs, logs you in
gws auth login       # subsequent scope selection and login"><pre>gws auth setup       <span class="pl-c"><span class="pl-c">#</span> one-time: creates a Cloud project, enables APIs, logs you in</span>
gws auth login       <span class="pl-c"><span class="pl-c">#</span> subsequent scope selection and login</span></pre></div>
<blockquote>
<p dir="auto"><code>gws auth setup</code> requires the <a href="https://cloud.google.com/sdk/docs/install" rel="nofollow"><code>gcloud</code> CLI</a>. If you don't have <code>gcloud</code>, use the <a href="#manual-oauth-setup-google-cloud-console">manual setup</a> below instead.</p>
</blockquote>
<div class="markdown-alert markdown-alert-warning" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-alert mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>Warning</p><p dir="auto"><strong>Scope limits in testing mode:</strong> If your OAuth app is unverified (testing mode),
Google limits consent to ~25 scopes. The <code>recommended</code> scope preset includes 85+
scopes and <strong>will fail</strong> for unverified apps (especially for <code>@gmail.com</code> accounts).
Choose individual services instead to filter the scope picker:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth login -s drive,gmail,sheets"><pre>gws auth login -s drive,gmail,sheets</pre></div>
</div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Manual OAuth setup (Google Cloud Console)</h3><a id="user-content-manual-oauth-setup-google-cloud-console" class="anchor" aria-label="Permalink: Manual OAuth setup (Google Cloud Console)" href="#manual-oauth-setup-google-cloud-console"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use this when <code>gws auth setup</code> cannot automate project/client creation, or when you want explicit control.</p>
<ol dir="auto">
<li>Open Google Cloud Console in the target project:
<ul dir="auto">
<li>OAuth consent screen: <code>https://console.cloud.google.com/apis/credentials/consent?project=&lt;PROJECT_ID&gt;</code></li>
<li>Credentials: <code>https://console.cloud.google.com/apis/credentials?project=&lt;PROJECT_ID&gt;</code></li>
</ul>
</li>
<li>Configure OAuth branding/audience if prompted:
<ul dir="auto">
<li>App type: <strong>External</strong> (testing mode is fine)</li>
</ul>
</li>
<li>Add your account under <strong>Test users</strong></li>
<li>Create an OAuth client:
<ul dir="auto">
<li>Type: <strong>Desktop app</strong></li>
</ul>
</li>
<li>Download the client JSON and save it to:
<ul dir="auto">
<li><code>~/.config/gws/client_secret.json</code></li>
</ul>
</li>
</ol>
<div class="markdown-alert markdown-alert-important" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-report mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>Important</p><p dir="auto"><strong>You must add yourself as a test user.</strong> In the OAuth consent screen, click
<strong>Test users → Add users</strong> and enter your Google account email. Without this,
login will fail with a generic "Access blocked" error.</p>
</div>
<p dir="auto">Then run:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth login"><pre>gws auth login</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Browser-assisted auth (human or agent)</h3><a id="user-content-browser-assisted-auth-human-or-agent" class="anchor" aria-label="Permalink: Browser-assisted auth (human or agent)" href="#browser-assisted-auth-human-or-agent"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">You can complete OAuth either manually or with browser automation.</p>
<ul dir="auto">
<li><strong>Human flow</strong>: run <code>gws auth login</code>, open the printed URL, approve scopes.</li>
<li><strong>Agent-assisted flow</strong>: the agent opens the URL, selects account, handles consent prompts, and returns control once the localhost callback succeeds.</li>
</ul>
<p dir="auto">If consent shows <strong>"Google hasn't verified this app"</strong> (testing mode), click <strong>Continue</strong>.
If scope checkboxes appear, select required scopes (or <strong>Select all</strong>) before continuing.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Headless / CI (export flow)</h3><a id="user-content-headless--ci-export-flow" class="anchor" aria-label="Permalink: Headless / CI (export flow)" href="#headless--ci-export-flow"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>Complete interactive auth on a machine with a browser.</li>
<li>Export credentials:
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth export --unmasked &gt; credentials.json"><pre>gws auth <span class="pl-k">export</span> --unmasked <span class="pl-k">&gt;</span> credentials.json</pre></div>
</li>
<li>On the headless machine:
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json
gws drive files list   # just works"><pre><span class="pl-k">export</span> GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json
gws drive files list   <span class="pl-c"><span class="pl-c">#</span> just works</span></pre></div>
</li>
</ol>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Service Account (server-to-server)</h3><a id="user-content-service-account-server-to-server" class="anchor" aria-label="Permalink: Service Account (server-to-server)" href="#service-account-server-to-server"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Point to your key file; no login needed.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json
gws drive files list"><pre><span class="pl-k">export</span> GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json
gws drive files list</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Pre-obtained Access Token</h3><a id="user-content-pre-obtained-access-token" class="anchor" aria-label="Permalink: Pre-obtained Access Token" href="#pre-obtained-access-token"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Useful when another tool (e.g. <code>gcloud</code>) already mints tokens for your environment.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export GOOGLE_WORKSPACE_CLI_TOKEN=$(gcloud auth print-access-token)"><pre><span class="pl-k">export</span> GOOGLE_WORKSPACE_CLI_TOKEN=<span class="pl-s"><span class="pl-pds">$(</span>gcloud auth print-access-token<span class="pl-pds">)</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Precedence</h3><a id="user-content-precedence" class="anchor" aria-label="Permalink: Precedence" href="#precedence"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Priority</th>
<th>Source</th>
<th>Set via</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Access token</td>
<td><code>GOOGLE_WORKSPACE_CLI_TOKEN</code></td>
</tr>
<tr>
<td>2</td>
<td>Credentials file</td>
<td><code>GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE</code></td>
</tr>
<tr>
<td>3</td>
<td>Encrypted credentials</td>
<td><code>gws auth login</code></td>
</tr>
<tr>
<td>4</td>
<td>Plaintext credentials</td>
<td><code>~/.config/gws/credentials.json</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">Environment variables can also live in a <code>.env</code> file.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">AI Agent Skills</h2><a id="user-content-ai-agent-skills" class="anchor" aria-label="Permalink: AI Agent Skills" href="#ai-agent-skills"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The repo ships 100+ Agent Skills (<code>SKILL.md</code> files) — one for every supported API, plus higher-level helpers for common workflows and 50 curated recipes for Gmail, Drive, Docs, Calendar, and Sheets. See the full <a href="docs/skills.md">Skills Index</a> for the complete list.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Install all skills at once
npx skills add https://github.com/googleworkspace/cli

# Or pick only what you need
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-drive
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-gmail"><pre><span class="pl-c"><span class="pl-c">#</span> Install all skills at once</span>
npx skills add https://github.com/googleworkspace/cli

<span class="pl-c"><span class="pl-c">#</span> Or pick only what you need</span>
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-drive
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-gmail</pre></div>
<details>
<summary>OpenClaw setup</summary>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Symlink all skills (stays in sync with repo)
ln -s $(pwd)/skills/gws-* ~/.openclaw/skills/

# Or copy specific skills
cp -r skills/gws-drive skills/gws-gmail ~/.openclaw/skills/"><pre><span class="pl-c"><span class="pl-c">#</span> Symlink all skills (stays in sync with repo)</span>
ln -s <span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>/skills/gws-<span class="pl-k">*</span> <span class="pl-k">~</span>/.openclaw/skills/

<span class="pl-c"><span class="pl-c">#</span> Or copy specific skills</span>
cp -r skills/gws-drive skills/gws-gmail <span class="pl-k">~</span>/.openclaw/skills/</pre></div>
<p dir="auto">The <code>gws-shared</code> skill includes an <code>install</code> block so OpenClaw auto-installs the CLI via <code>npm</code> if <code>gws</code> isn't on PATH.</p>
</details>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Gemini CLI Extension</h2><a id="user-content-gemini-cli-extension" class="anchor" aria-label="Permalink: Gemini CLI Extension" href="#gemini-cli-extension"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li>
<p dir="auto">Authenticate the CLI first:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth setup"><pre>gws auth setup</pre></div>
</li>
<li>
<p dir="auto">Install the extension into the Gemini CLI:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gemini extensions install https://github.com/googleworkspace/cli"><pre>gemini extensions install https://github.com/googleworkspace/cli</pre></div>
</li>
</ol>
<p dir="auto">Installing this extension gives your Gemini CLI agent direct access to all <code>gws</code> commands and Google Workspace agent skills. Because <code>gws</code> handles its own authentication securely, you simply need to authenticate your terminal once prior to using the agent, and the extension will automatically inherit your credentials.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Advanced Usage</h2><a id="user-content-advanced-usage" class="anchor" aria-label="Permalink: Advanced Usage" href="#advanced-usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Multipart Uploads</h3><a id="user-content-multipart-uploads" class="anchor" aria-label="Permalink: Multipart Uploads" href="#multipart-uploads"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws drive files create --json '{&quot;name&quot;: &quot;report.pdf&quot;}' --upload ./report.pdf"><pre>gws drive files create --json <span class="pl-s"><span class="pl-pds">'</span>{"name": "report.pdf"}<span class="pl-pds">'</span></span> --upload ./report.pdf</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Pagination</h3><a id="user-content-pagination" class="anchor" aria-label="Permalink: Pagination" href="#pagination"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Flag</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--page-all</code></td>
<td>Auto-paginate, one JSON line per page (NDJSON)</td>
<td>off</td>
</tr>
<tr>
<td><code>--page-limit &lt;N&gt;</code></td>
<td>Max pages to fetch</td>
<td>10</td>
</tr>
<tr>
<td><code>--page-delay &lt;MS&gt;</code></td>
<td>Delay between pages</td>
<td>100 ms</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Google Sheets — Shell Escaping</h3><a id="user-content-google-sheets--shell-escaping" class="anchor" aria-label="Permalink: Google Sheets — Shell Escaping" href="#google-sheets--shell-escaping"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Sheets ranges use <code>!</code> which bash interprets as history expansion. Always wrap values in <strong>single quotes</strong>:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Read cells A1:C10 from &quot;Sheet1&quot;
gws sheets spreadsheets values get \
  --params '{&quot;spreadsheetId&quot;: &quot;SPREADSHEET_ID&quot;, &quot;range&quot;: &quot;Sheet1!A1:C10&quot;}'

# Append rows
gws sheets spreadsheets values append \
  --params '{&quot;spreadsheetId&quot;: &quot;ID&quot;, &quot;range&quot;: &quot;Sheet1!A1&quot;, &quot;valueInputOption&quot;: &quot;USER_ENTERED&quot;}' \
  --json '{&quot;values&quot;: [[&quot;Name&quot;, &quot;Score&quot;], [&quot;Alice&quot;, 95]]}'"><pre><span class="pl-c"><span class="pl-c">#</span> Read cells A1:C10 from "Sheet1"</span>
gws sheets spreadsheets values get \
  --params <span class="pl-s"><span class="pl-pds">'</span>{"spreadsheetId": "SPREADSHEET_ID", "range": "Sheet1!A1:C10"}<span class="pl-pds">'</span></span>

<span class="pl-c"><span class="pl-c">#</span> Append rows</span>
gws sheets spreadsheets values append \
  --params <span class="pl-s"><span class="pl-pds">'</span>{"spreadsheetId": "ID", "range": "Sheet1!A1", "valueInputOption": "USER_ENTERED"}<span class="pl-pds">'</span></span> \
  --json <span class="pl-s"><span class="pl-pds">'</span>{"values": [["Name", "Score"], ["Alice", 95]]}<span class="pl-pds">'</span></span></pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Model Armor (Response Sanitization)</h3><a id="user-content-model-armor-response-sanitization" class="anchor" aria-label="Permalink: Model Armor (Response Sanitization)" href="#model-armor-response-sanitization"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Integrate <a href="https://cloud.google.com/security/products/model-armor" rel="nofollow">Google Cloud Model Armor</a> to scan API responses for prompt injection before they reach your agent.</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws gmail users messages get --params '...' \
  --sanitize &quot;projects/P/locations/L/templates/T&quot;"><pre>gws gmail users messages get --params <span class="pl-s"><span class="pl-pds">'</span>...<span class="pl-pds">'</span></span> \
  --sanitize <span class="pl-s"><span class="pl-pds">"</span>projects/P/locations/L/templates/T<span class="pl-pds">"</span></span></pre></div>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Variable</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE</code></td>
<td>Default Model Armor template</td>
</tr>
<tr>
<td><code>GOOGLE_WORKSPACE_CLI_SANITIZE_MODE</code></td>
<td><code>warn</code> (default) or <code>block</code></td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Environment Variables</h2><a id="user-content-environment-variables" class="anchor" aria-label="Permalink: Environment Variables" href="#environment-variables"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">All variables are optional. See <a href=".env.example"><code>.env.example</code></a> for a copy-paste template.</p>
<markdown-accessiblity-table><table>
<thead>
<tr>
<th>Variable</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>GOOGLE_WORKSPACE_CLI_TOKEN</code></td>
<td>Pre-obtained OAuth2 access token (highest priority)</td>
</tr>
<tr>
<td><code>GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE</code></td>
<td>Path to OAuth credentials JSON (user or service account)</td>
</tr>
</tbody>
</table></markdown-accessiblity-table>
<p dir="auto">| <code>GOOGLE_WORKSPACE_CLI_CLIENT_ID</code> | OAuth client ID (alternative to <code>client_secret.json</code>) |
| <code>GOOGLE_WORKSPACE_CLI_CLIENT_SECRET</code> | OAuth client secret (paired with <code>CLIENT_ID</code>) |
| <code>GOOGLE_WORKSPACE_CLI_CONFIG_DIR</code> | Override config directory (default: <code>~/.config/gws</code>) |
| <code>GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE</code> | Default Model Armor template |
| <code>GOOGLE_WORKSPACE_CLI_SANITIZE_MODE</code> | <code>warn</code> (default) or <code>block</code> |
| <code>GOOGLE_WORKSPACE_PROJECT_ID</code> | GCP project ID override for quota/billing and fallback for helper commands |</p>
<p dir="auto">Environment variables can also be set in a <code>.env</code> file (loaded via <a href="https://crates.io/crates/dotenvy" rel="nofollow">dotenvy</a>).</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Architecture</h2><a id="user-content-architecture" class="anchor" aria-label="Permalink: Architecture" href="#architecture"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>gws</code> uses a <strong>two-phase parsing</strong> strategy:</p>
<ol dir="auto">
<li>Read <code>argv[1]</code> to identify the service (e.g. <code>drive</code>)</li>
<li>Fetch the service's Discovery Document (cached 24 h)</li>
<li>Build a <code>clap::Command</code> tree from the document's resources and methods</li>
<li>Re-parse the remaining arguments</li>
<li>Authenticate, build the HTTP request, execute</li>
</ol>
<p dir="auto">All output — success, errors, download metadata — is structured JSON.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Troubleshooting</h2><a id="user-content-troubleshooting" class="anchor" aria-label="Permalink: Troubleshooting" href="#troubleshooting"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">"Access blocked" or 403 during login</h3><a id="user-content-access-blocked-or-403-during-login" class="anchor" aria-label="Permalink: &quot;Access blocked&quot; or 403 during login" href="#access-blocked-or-403-during-login"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Your OAuth app is in <strong>testing mode</strong> and your account is not listed as a test user.</p>
<p dir="auto"><strong>Fix:</strong> Open the <a href="https://console.cloud.google.com/apis/credentials/consent" rel="nofollow">OAuth consent screen</a> in your GCP project → <strong>Test users</strong> → <strong>Add users</strong> → enter your Google account email. Then retry <code>gws auth login</code>.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">"Google hasn't verified this app"</h3><a id="user-content-google-hasnt-verified-this-app" class="anchor" aria-label="Permalink: &quot;Google hasn't verified this app&quot;" href="#google-hasnt-verified-this-app"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Expected when your app is in testing mode. Click <strong>Advanced</strong> → <strong>Go to &lt;app name&gt; (unsafe)</strong> to proceed. This is safe for personal use; verification is only required to publish the app to other users.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">Too many scopes / consent screen error</h3><a id="user-content-too-many-scopes--consent-screen-error" class="anchor" aria-label="Permalink: Too many scopes / consent screen error" href="#too-many-scopes--consent-screen-error"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Unverified (testing mode) apps are limited to ~25 OAuth scopes. The <code>recommended</code> scope preset includes many scopes and will exceed this limit.</p>
<p dir="auto"><strong>Fix:</strong> Select only the scopes you need:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="gws auth login --scopes drive,gmail,calendar"><pre>gws auth login --scopes drive,gmail,calendar</pre></div>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto"><code>gcloud</code> CLI not found</h3><a id="user-content-gcloud-cli-not-found" class="anchor" aria-label="Permalink: gcloud CLI not found" href="#gcloud-cli-not-found"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto"><code>gws auth setup</code> requires the <code>gcloud</code> CLI to automate project creation. You have three options:</p>
<ol dir="auto">
<li><a href="https://cloud.google.com/sdk/docs/install" rel="nofollow">Install gcloud</a> and use <code>gcloud</code> directly.</li>
<li>Re-run <code>gws auth setup</code> which wraps <code>gcloud</code> calls.</li>
<li>Skip <code>gcloud</code> entirely — set up OAuth credentials manually in the <a href="#manual-oauth-setup-google-cloud-console">Cloud Console</a></li>
</ol>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto"><code>redirect_uri_mismatch</code></h3><a id="user-content-redirect_uri_mismatch" class="anchor" aria-label="Permalink: redirect_uri_mismatch" href="#redirect_uri_mismatch"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The OAuth client was not created as a <strong>Desktop app</strong> type. In the <a href="https://console.cloud.google.com/apis/credentials" rel="nofollow">Credentials</a> page, delete the existing client, create a new one with type <strong>Desktop app</strong>, and download the new JSON.</p>
<div class="markdown-heading" dir="auto"><h3 class="heading-element" dir="auto">API not enabled — <code>accessNotConfigured</code></h3><a id="user-content-api-not-enabled--accessnotconfigured" class="anchor" aria-label="Permalink: API not enabled — accessNotConfigured" href="#api-not-enabled--accessnotconfigured"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If a required Google API is not enabled for your GCP project, you will see a
403 error with reason <code>accessNotConfigured</code>:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;error&quot;: {
    &quot;code&quot;: 403,
    &quot;message&quot;: &quot;Gmail API has not been used in project 549352339482 ...&quot;,
    &quot;reason&quot;: &quot;accessNotConfigured&quot;,
    &quot;enable_url&quot;: &quot;https://console.developers.google.com/apis/api/gmail.googleapis.com/overview?project=549352339482&quot;
  }
}"><pre>{
  <span class="pl-ent">"error"</span>: {
    <span class="pl-ent">"code"</span>: <span class="pl-c1">403</span>,
    <span class="pl-ent">"message"</span>: <span class="pl-s"><span class="pl-pds">"</span>Gmail API has not been used in project 549352339482 ...<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"reason"</span>: <span class="pl-s"><span class="pl-pds">"</span>accessNotConfigured<span class="pl-pds">"</span></span>,
    <span class="pl-ent">"enable_url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://console.developers.google.com/apis/api/gmail.googleapis.com/overview?project=549352339482<span class="pl-pds">"</span></span>
  }
}</pre></div>
<p dir="auto"><code>gws</code> also prints an actionable hint to <strong>stderr</strong>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="💡 API not enabled for your GCP project.
   Enable it at: https://console.developers.google.com/apis/api/gmail.googleapis.com/overview?project=549352339482
   After enabling, wait a few seconds and retry your command."><pre class="notranslate"><code>💡 API not enabled for your GCP project.
   Enable it at: https://console.developers.google.com/apis/api/gmail.googleapis.com/overview?project=549352339482
   After enabling, wait a few seconds and retry your command.
</code></pre></div>
<p dir="auto"><strong>Steps to fix:</strong></p>
<ol dir="auto">
<li>Click the <code>enable_url</code> link (or copy it from the <code>enable_url</code> JSON field).</li>
<li>In the GCP Console, click <strong>Enable</strong>.</li>
<li>Wait ~10 seconds, then retry your <code>gws</code> command.</li>
</ol>
<div class="markdown-alert markdown-alert-tip" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-light-bulb mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"></path></svg>Tip</p><p dir="auto">You can also run <code>gws auth setup</code> which walks you through enabling all required
APIs for your project automatically.</p>
</div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Development</h2><a id="user-content-development" class="anchor" aria-label="Permalink: Development" href="#development"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cargo build                       # dev build
cargo clippy -- -D warnings       # lint
cargo test                        # unit tests
./scripts/coverage.sh             # HTML coverage report → target/llvm-cov/html/"><pre>cargo build                       <span class="pl-c"><span class="pl-c">#</span> dev build</span>
cargo clippy -- -D warnings       <span class="pl-c"><span class="pl-c">#</span> lint</span>
cargo <span class="pl-c1">test</span>                        <span class="pl-c"><span class="pl-c">#</span> unit tests</span>
./scripts/coverage.sh             <span class="pl-c"><span class="pl-c">#</span> HTML coverage report → target/llvm-cov/html/</span></pre></div>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">License</h2><a id="user-content-license" class="anchor" aria-label="Permalink: License" href="#license"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Apache-2.0</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Disclaimer</h2><a id="user-content-disclaimer" class="anchor" aria-label="Permalink: Disclaimer" href="#disclaimer"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-alert markdown-alert-caution" dir="auto"><p class="markdown-alert-title" dir="auto"><svg class="octicon octicon-stop mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Caution</p><p dir="auto">This is <strong>not</strong> an officially supported Google product.</p>
</div>
</article></div>]]></description>
      <link>https://github.com/googleworkspace/cli</link>
      <guid>https://github.com/googleworkspace/cli</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Pro-Human AI Declaration]]></title>
      <description><![CDATA[<section id="section-1167-9" class="ct-section hero-section-homepage hero-section-homepage-desktop breakout--full"><div class="ct-section-inner-wrap ct-div-block"><div id="_rich_text-359-9" class="oxy-rich-text" data-aos="fade" data-aos-duration="400" data-aos-delay="200" data-aos-once="true"><p>March 2026</p></div></div></section><section id="section-1189-9" class="ct-section hero-section-homepage hero-section-homepage-mobile"><div class="ct-section-inner-wrap"><div id="div_block-1681-9" class="ct-div-block"><div id="_rich_text-2429-1681" class="oxy-rich-text" data-aos="fade" data-aos-duration="400" data-aos-delay="200" data-aos-once="true"><p>March 2026</p></div></div><img id="image-1676-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/van-nola-mobile.png" class="ct-image breakout--full" srcset="https://humanstatement.org/wp-content/uploads/2026/02/van-nola-mobile.png 563w, https://humanstatement.org/wp-content/uploads/2026/02/van-nola-mobile-300x269.png 300w" sizes="(max-width: 563px) 100vw, 563px" /></div></section><section id="section-62-9" class="ct-section gap--xl"><div class="ct-section-inner-wrap ct-div-block grid--l-1 gap--l body-main-content"><div id="div_block-358-9" class="ct-div-block"><div id="div_block-1594-9" class="ct-div-block"><div id="_rich_text-1388-9" class="oxy-rich-text"><p><em>As companies race to develop and deploy AI systems, humanity faces a fork in the road. One path is a race to replace: humans replaced as creators, counselors, caregivers and companions, then in most jobs and decision-making roles, concentrating ever more power in unaccountable institutions and their machines. An influential fringe even advocates <a href="https://blog.samaltman.com/the-merge" target="_blank" rel="noopener">altering</a> or <a href="https://www.youtube.com/watch?v=NgHFMolXs3U" target="_blank" rel="noopener">replacing</a> humanity itself. This race to replace poses risks to societal stability, national security, economic prosperity, civil liberties, privacy, and democratic governance. It also imperils the human experiences of childhood and family, faith, and community.</em></p><p><em>A remarkably broad coalition rejects this path, united by a simple conviction: artificial intelligence should serve humanity, not the reverse. There is a better path, where trustworthy and controllable AI tools amplify rather than diminish human potential, empower people, enhance human dignity, protect individual liberty, strengthen families and communities, preserve self-governance and help create unprecedented health and prosperity. This path demands that those who wield technological power be accountable to human values and needs, in support of human flourishing.</em></p></div></div><div id="div_block-1834-9" class="ct-div-block"><div id="div_block-1394-9" class="ct-div-block"><a id="link-1392-9" class="ct-link" href="#keeping-humans-in-charge">
<p>1. Keeping Humans in Charge</p>
</a><a id="link-1389-9" class="ct-link" href="#avoiding-concentration-of-power">
<p>2. Avoiding Concentration of Power</p>
</a><a id="link-1398-9" class="ct-link" href="#protecting-the-human-experience">
<p>3. Protecting the Human Experience</p>
</a><a id="link-1400-9" class="ct-link" href="#human-agency-and-liberty">
<p>4. Human Agency and Liberty</p>
</a><a id="link-1402-9" class="ct-link" href="#responsibility-and-accountability">
<p>5. Responsibility and Accountability for AI Companies</p>
</a><div id="div_block-2019-9" class="ct-div-block cursor--pointer"><img id="image-2020-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/signatory-icon.png" class="ct-image" srcset="" sizes="(max-width: 39px) 100vw, 39px" /><a id="text_block-2021-9" class="ct-link-text" href="#signatures">Skip to endorsers</a></div></div><div id="div_block-1839-9" class="ct-div-block"><div id="div_block-1596-9" class="ct-div-block chapter-div"><div id="_rich_text-1598-9" class="oxy-rich-text chapter-rich-text"><p><strong>Human Control Is Non-Negotiable:</strong> Humanity must remain in control. Humans should choose how and whether to delegate decisions to AI systems.</p><p><strong>Meaningful Human Control:</strong> Humans should have authority and capacity to understand, guide, proscribe, and override AI systems.</p><p><strong>No Superintelligence Race:</strong> Development of superintelligence should be prohibited until there is broad scientific consensus that it can be done safely and controllably, and there is strong public buy-in.</p><p><strong>Off-Switch:</strong> Powerful AI systems must have mechanisms that allow human operators to promptly shut them down.</p><p><strong>No Reckless Architectures:</strong> AI systems must not be designed so that they can self-replicate, autonomously self-improve, resist shutdown, or control weapons of mass destruction.</p><p><strong>Independent Oversight:</strong> Highly autonomous AI systems where controllability is not obvious require pre-development review and independent oversight: genuine authority to understand, prohibit, and override, not industry self-regulation.</p><p><strong>Capability Honesty:</strong> AI companies must provide clear, accurate and honest representations of their systems' capabilities and limitations.</p></div></div><div id="div_block-2450-9" class="ct-div-block"><div id="div_block-2471-9" class="ct-div-block"><p><strong>Polling Results</strong> | March 2026</p><p>1004 likely voters via web panels, weighted by gender, race, education, 2024 presidential vote and age.</p></div><div id="div_block-2474-9" class="ct-div-block"><p>Americans chose human control over speed by 8 to 1</p><img id="image-2470-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/03/Americans-support-prohuman-declaration.png" class="ct-image" srcset="https://humanstatement.org/wp-content/uploads/2026/03/Americans-support-prohuman-declaration.png 748w, https://humanstatement.org/wp-content/uploads/2026/03/Americans-support-prohuman-declaration-300x54.png 300w" sizes="(max-width: 748px) 100vw, 748px" /><img id="image-2483-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/03/Americans-support-prohuman-declaration-mobile.png" class="ct-image" srcset="https://humanstatement.org/wp-content/uploads/2026/03/Americans-support-prohuman-declaration-mobile.png 748w, https://humanstatement.org/wp-content/uploads/2026/03/Americans-support-prohuman-declaration-mobile-300x212.png 300w" sizes="(max-width: 748px) 100vw, 748px" /><div id="div_block-2465-9" class="ct-div-block grid--3 gap--m grid--s-1"><div id="div_block-2456-9" class="ct-div-block"><p>73%</p><p>want children protected from manipulative AI</p></div><div id="div_block-2459-9" class="ct-div-block"><p>72%</p><p>believe AI companies should be legally responsible for harms</p></div><div id="div_block-2462-9" class="ct-div-block"><p>69%</p><p>want superintelligence prohibited until proven safe</p></div></div></div><a id="link-2468-9" class="ct-link" href="https://humanstatement.org/poll-americans-support-pro-human-principles/">
<p>View polling results →</p>
</a></div><div id="div_block-1844-9" class="ct-div-block"><img id="image-1841-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png" class="ct-image declaration-section-separator" srcset="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png 336w, https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator-300x96.png 300w" sizes="(max-width: 336px) 100vw, 336px" /></div><div id="div_block-1835-9" class="ct-div-block chapter-div"><div id="_rich_text-1837-9" class="oxy-rich-text chapter-rich-text"><p><strong>No AI Monopolies:</strong> AI monopolies that concentrate power, stifle innovation, and imperil entrepreneurship must be avoided.</p><p><strong>Shared Prosperity:</strong> The benefits and economic prosperity created by AI should be shared broadly.</p><p><strong>No Corporate Welfare:</strong> AI corporations should not be exempted from regulatory oversight or receive government bailouts.</p><p><strong>Genuine Value Creation:</strong> AI development should prioritize solving real problems and creating authentic value.</p><p><strong>Democratic Authority Over Major Transitions:</strong> Decisions about AI's role in transforming work, society, and civic life require democratic support, not unilateral corporate or government decree.</p><p><strong>Avoid Societal Lock-In:</strong> AI development must not severely limit humanity's future options or irreversibly limit our agency over our future.</p></div></div><div id="div_block-1863-9" class="ct-div-block"><img id="image-1864-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png" class="ct-image declaration-section-separator" srcset="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png 336w, https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator-300x96.png 300w" sizes="(max-width: 336px) 100vw, 336px" /></div><div id="div_block-1860-9" class="ct-div-block chapter-div"><div id="_rich_text-1862-9" class="oxy-rich-text chapter-rich-text"><p><strong>Defense of Family and Community Bonds:</strong> AI should not supplant the foundational relationships that give life meaning—family, friendship, faith communities, and local connections.</p><p><strong>Child Protection:</strong> Companies must not be allowed to exploit children or undermine their wellbeing with AI interactions creating emotional attachment or leverage.</p><p><strong>Right to Grow:</strong> AI companies should not be allowed to stunt children's physical, mental or social growth or deprive them of essential experiences for healthy development during critical periods.</p><p><strong>Pre-Deployment Safety Testing:</strong> Like drugs, chatbots must undergo pre-deployment testing for increased suicidal ideation, exacerbation of mental health disorders, escalation of acute crisis situations, and other known harms.</p><p><strong>Bot-or-Not Labeling:</strong> AI-generated content that could reasonably be mistaken for human-generated must be clearly labeled as such.</p><p><strong>No Deceptive Identity:</strong> AI should clearly and correctly identify itself as artificial, nonhuman, and not a professional, and it should not claim experiences it lacks.</p><p><strong>No Behavioral Addiction:</strong> AIs should not cause addiction or compulsive use through manipulation, sycophantic validation, or attachment formation.</p></div></div><div id="div_block-1871-9" class="ct-div-block"><img id="image-1872-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png" class="ct-image declaration-section-separator" srcset="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png 336w, https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator-300x96.png 300w" sizes="(max-width: 336px) 100vw, 336px" /></div><div id="div_block-1873-9" class="ct-div-block chapter-div"><div id="_rich_text-1875-9" class="oxy-rich-text chapter-rich-text"><p><strong>No AI Personhood:</strong> AI systems must not be granted legal personhood, and AI systems should not be designed such that they deserve personhood.</p><p><strong>Trustworthiness:</strong> AI must be transparent, accountable, reliable, and free from perverse private or authoritarian interests.</p><p><strong>Liberty:</strong> AI must not curtail individual liberty, freedom of speech, religious practice, or association.</p><p><strong>Data Rights and Privacy:</strong> People should have power over their personal data, with rights to access, correct, and delete it from active systems, AI training sets, and derived inferences.</p><p><strong>Psychological Privacy:</strong> AI should not be allowed to exploit data about the mental or emotional states of users.</p><p><strong>Avoiding Enfeeblement:</strong> AI systems should be designed to empower, rather than enfeeble their users.</p></div></div><div id="div_block-1869-9" class="ct-div-block"><img id="image-1870-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png" class="ct-image declaration-section-separator" srcset="https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator.png 336w, https://humanstatement.org/wp-content/uploads/2026/02/Section-Separator-300x96.png 300w" sizes="(max-width: 336px) 100vw, 336px" /></div><div id="div_block-1876-9" class="ct-div-block chapter-div"><div id="_rich_text-1878-9" class="oxy-rich-text chapter-rich-text"><p><strong>No Liability Shield:</strong> AI must not be able to act as a liability shield, preventing those deploying it from being legally responsible for their actions.</p><p><strong>Developer Liability:</strong> Developers and deployers bear legal liability for defects, misrepresentation of capabilities, and inadequate safety controls, with statutes of limitation that account for harms emerging over time.</p><p><strong>Personal Liability:</strong> There should be criminal penalties for executives responsible for prohibited child-targeted systems or ones causing catastrophic harm.</p><p><strong>Independent Safety Standards:</strong> AI development shall be governed by independent safety standards and rigorous oversight.</p><p><strong>No Regulatory Capture:</strong> AI companies must not be allowed undue influence over rules that govern them.</p><p><strong>Failure Transparency:</strong> If an AI system causes harm, it should be possible to ascertain why as well as who is responsible.</p><p><strong>AI Loyalty:</strong> AI systems performing functions in professions with fiduciary duties, such as health, finance, law, or therapy, must fulfill all of those duties, including mandated reporting, duty of care, conflict of interest disclosure, and informed consent.</p></div></div></div></div><div id="div_block-2484-9" class="ct-div-block flex--row padding--s bg--primary-trans-10 flex--col-m margin-top--l"><div id="div_block-2485-9" class="ct-div-block"><p>Join the pro-human movement for commonsense regulation to keep AI safe and under our control.</p></div><div id="div_block-2486-9" class="ct-div-block"><a id="link_button-2487-9" class="ct-link-button btn--primary" href="https://protectwhatshuman.org/#join" target="_blank">Join the Pro-human mailing list ↗</a><p>Takes you to our companion website titled ‘<strong>Protect What’s Human</strong>’ where you can sign up.</p></div></div></div><div id="div_block-361-9" class="ct-div-block"><div id="signatures" class="ct-div-block padding--xs" data-aos="fade" data-aos-duration="500" data-aos-delay="1000" data-aos-once="true"><div id="form-modal-activator" class="ct-div-block cursor--pointer"><img id="image-1549-9" alt="" src="https://humanstatement.org/wp-content/uploads/2026/02/signatory-icon.png" class="ct-image" srcset="" sizes="(max-width: 39px) 100vw, 39px" /><p>Endorse the Declaration</p></div><div id="_dynamic_list-2340-9" class="oxy-dynamic-list organizations-repeater-sign-list"><p>Institute for Family Studies</p><p>The Congress of Christian Leaders</p><p>American Federation of Teachers</p><p>G20 Interfaith Forum Association</p><p>SAG-AFTRA</p><p>Progressive Democrats of America (PDA)</p><p>Blessed Mother Family Foundation</p><p>David’s Legacy Foundation</p><p>Parents RISE!</p><p>Center for Study of Responsive Law</p><p>Center for AI and Digital Policy</p><p>Future of Life Institute</p><p>Humans First</p><p>Center for Humane Technology</p><p>ControlAI</p><p>CivAI</p><p>Pause AI</p><p>Saving Ourselves Foundation Inc.</p><p>Center for Responsible Technology</p><p>The B Team</p><p>Fathom</p><p>Faith Matters</p><p>Human Change Foundation</p><p>Seismic Foundation</p><p>Servitium AI and Serviti Corp</p><p>Legal Advocates for Safe Science and Technology</p><p>Economic Security Project</p><p>Tech Oversight Project</p><p>Design It For Us</p><p>AI Ethics and Governance Institute</p><p>Organized Intelligence</p><p>Evitable</p><p>Encode</p><p>Tech Equity</p><p>The Alliance for Secure AI</p><p>Ethical Tech Project</p><p>Essential Information</p><p>Common Cause</p><p>Common Cause California</p><p>Public Citizen</p><p>Heat Initiative</p><p>Civilization Research Institute</p><p>Demand Progress Education Fund</p><p>OpenMined</p><p>Center for Safe AGI</p><p>GuardRailNow/The AI Risk Network</p><p>Agape Kingdom</p><p>Torchbearer Community</p><p>Convictional, Inc.</p><p>Odlum Global Strategies</p><p>Ethagi Inc.</p><p>Open MIC (Open Media and Information Companies Initiative)</p><p>Ridy</p><p>The Unwritten Future</p><p>AI Point EU</p><p>The HumAIne Foundation</p><p>Doom Debates</p><p>New Polity Magazine</p><p>The Altern Research Collective for Brains, Minds &amp; Machines</p><p>AI Commons</p><p>Globaïa</p><p>London Futurists</p><p>Brand Innovation</p><p>AI Safety Initiative at Georgia Tech</p><p>Analogik</p><p>Luella</p><p>Athena© Organization Labs</p><p>Exponential Infrastructure for Coordination</p><p>Simuliz Interactive S.A.S</p><p>Forschungsnetzwerk Extraterrestrische Intelligenz (Extraterrestrial Intelligence Research Network)</p><p>Life Itself</p><p>True North Tutors</p><p>Geopolitical Insight and Education Foundation</p><p>Art-Labyrinth</p><p>The Israeli Association for Ethics in AI</p><p>Augmentifai</p><p>Humanity</p><p>Humainary</p><p>The Fellowship of Sovereign Consciousness</p><p>Equashield</p><p>Ethicalainow.org</p><p>Nexigen</p><p>sportphotoevents.com</p><p>The AI Trust Council</p><p>Protect Democracy</p><p>Occupy Earth</p><p>AI Safety Connect</p><p>Snowgorilla Media</p><p>AI Law Hub</p><p>Decentralised Human Architecture Foundation</p><p>PHI INSTITUTE for Augmented Intelligence</p><p>Indian Society of Artificial Intelligence and Law</p><p>Phenomenological AI Safety Research Institute</p><p>Nannestad vgs</p><p>Alignmint</p><p>One Mental Hub</p><p>Windfall Trust</p><p>Cross Labs</p><p>Effective Altruism Estonia</p><p>The Safe AI for Children Alliance</p><p>Vocitas AB</p><p>RevenueWIngs - Online Marketing Solutions Inc.</p><p>Alter.org.il</p><p>Ethical Sales Ltd</p><p>Art-Labyrinth</p><p>SAVE-Suicide Awareness Voices of Education</p><p>People First</p><p>SAFE AI Forever Inc.</p><p>E Gallina Art</p><p>L'angle</p><p>Five Intelligences Alliance</p><p>Talentor CZ</p><p>Coalition for a Baruch Plan for AI</p><p>BrixTec Web Soutions</p><p>Almma.AI</p><p>Sofia.edu</p><p>Maaind/Lifefire</p><p>IDEAS Research Institute</p><p>Psst.org</p><p>Our Fair Future</p><p>Center for Existential Safety</p><p>UFRGS</p><p>Grand Challenge AI</p><p>Buddhism &amp; AI Initiative</p><p>B+N Integrated Facility Services</p><p>Advancing Your Vision</p><p>Approachable Intelligence Research Foundation</p><p>Studiomadtulsa</p><p>Travel Lemming</p><p>AI Safety UAE</p><p>Smartphone Free Childhood US</p><p>Nuvint Dynamics</p><p>Techplomacy Foundation</p><p>Onward</p><p>The Human Line Project</p><p>Future of Work AI Labs</p><p>AI Recovery Collective</p><p>PT. Ksatria Mitra S</p><p>A Tree with Roots</p><p>Derrubando Muros</p><p>CeSIA - French Center for AI Safety</p><p>SynergiAI</p><p>Artificial Observer Limited</p><p>AI, Tech &amp; Privacy Academy</p><p>Cégep de Valleyfield</p></div><div id="_dynamic_list-2373-1672" class="oxy-dynamic-list signatories-repeater"><div id="div_block-2374-1672-1" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Yoshua Bengio Professor, Université de Montréal, Turing Award Laureate</p></div><div id="div_block-2374-1672-2" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Steve Bannon Fmr Executive Chairman of Breitbart News; fmr chief strategist to President Donald Trump; Host of War Room podcast</p></div><div id="div_block-2374-1672-3" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Susan Rice Fmr U.S. National Security Advisor &amp; Policy Advisor for President Obama; U.S. Ambassador to the United Nations; Rhodes Scholar</p></div><div id="div_block-2374-1672-4" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Glenn Beck Founder of Blaze media, radio host, TV personality, political commentator</p></div><div id="div_block-2374-1672-5" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alan Minsky Progressive Democrats of America (PDA)</p></div><div id="div_block-2374-1672-6" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Walter Kim President, National Association of Evangelicals, board member, Christianity Today</p></div><div id="div_block-2374-1672-7" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ralph Nader Consumer Advocate, Center for Study of Responsive Law, Presidential candidate</p></div><div id="div_block-2374-1672-8" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Daron Acemoğlu Nobel Laureate in Economics, MIT Institute Professor</p></div><div id="div_block-2374-1672-9" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Beatrice Fihn Nobel Peace Laureate, Founder of Lex International</p></div><div id="div_block-2374-1672-10" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rev. Johnnie Moore, PhD President, The Congress of Christian Leaders</p></div><div id="div_block-2374-1672-11" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Margarita Louis Dreyfus Human Change Foundation, Owner and chair of the Louis Dreyfus Company group, founder of Human Change Foundation</p></div><div id="div_block-2374-1672-12" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sir Richard Branson Founder, Virgin Group</p></div><div id="div_block-2374-1672-13" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Randi Weingarten President, American Federation of Teachers</p></div><div id="div_block-2374-1672-14" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Julianna Arnold Founding Member and Executive Director, Parents RISE!</p></div><div id="div_block-2374-1672-15" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Megan Garcia Blessed Mother Family Foundation</p></div><div id="div_block-2374-1672-16" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joann Bogard Parents SOS</p></div><div id="div_block-2374-1672-17" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael Toscano Director, Family First Technology Initiative, Senior Fellow, Institute for Family Studies</p></div><div id="div_block-2374-1672-18" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mike Kubzansky CEO, Omidyar Network, Professor of Computational Engineering, Rice University, Member: US National Academy of Engineering and National Academy of Sciences</p></div><div id="div_block-2374-1672-19" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Janet Vestal Kelly fmr. Virginia Secretary of Health and Human Resources; fmr. Secretary of the Commonwealth</p></div><div id="div_block-2374-1672-20" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tomicah Tillemann President, Project Liberty Institute</p></div><div id="div_block-2374-1672-21" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Stuart Russell Professor of Computer Science, Berkeley, Director of the Center for Human-Compatible Artificial Intelligence (CHAI); Co-author of the standard textbook 'Artificial Intelligence: a Modern Approach'</p></div><div id="div_block-2374-1672-22" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tristan Harris Co-Founder, Center for Humane Technology</p></div><div id="div_block-2374-1672-23" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brendan Steinhauser CEO, The Alliance for Secure AI</p></div><div id="div_block-2374-1672-24" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dawn Nakagawa President, Berggruen Institute</p></div><div id="div_block-2374-1672-25" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mikhail Samin Executive director, AI Governance and Safety Institute</p></div><div id="div_block-2374-1672-26" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jeffrey Bennett General Counsel, SAG-AFTRA</p></div><div id="div_block-2374-1672-27" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joseph-Gordon Levitt Actor, Filmmaker, Founder, HITRECORD</p></div><div id="div_block-2374-1672-28" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alyson Stoner Actress, dancer, and singer, SAG-AFTRA, known for Step Up, Camp Rock, and voicing Isabella in Phineas and Ferb.</p></div><div id="div_block-2374-1672-29" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Frances Fisher Actress, SAG-AFTRA, known for Titanic, Unforgiven, and Watchmen.</p></div><div id="div_block-2374-1672-30" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anthony Aguirre Future of Life Institute</p></div><div id="div_block-2374-1672-31" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Max Tegmark Future of Life Institute</p></div><div id="div_block-2374-1672-32" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Clark Barrett Professor of Computer Science, Stanford</p></div><div id="div_block-2374-1672-33" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Moshe Vardi Professor of Computational Engineering, Rice University, Member: US National Academy of Engineering and National Academy of Sciences</p></div><div id="div_block-2374-1672-34" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Autor Professor, Co-director, Stone Center on Inequality and Shaping the Future of Work, MIT Department of Economics,</p></div><div id="div_block-2374-1672-35" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Meredith Whittaker President, Signal Foundation</p></div><div id="div_block-2374-1672-36" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Emilia Javorsky Future of Life Institute</p></div><div id="div_block-2374-1672-37" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jean Oelwang Founding CEO, Virgin Unite and Planetary Guardians</p></div><div id="div_block-2374-1672-38" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Andrea Miotti Founder and CEO, ControlAI</p></div><div id="div_block-2374-1672-39" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marc Rotenberg Founder, Center for AI and Digital Policy</p></div><div id="div_block-2374-1672-40" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Malo Bourgon Machine Intelligence Research Institute</p></div><div id="div_block-2374-1672-41" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael Marinaccio Executive Director, Center for Responsible Technology</p></div><div id="div_block-2374-1672-42" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kelly Monroe Kullberg General Secretary, American Association of Evangelicals (AAE)</p></div><div id="div_block-2374-1672-43" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dylan Hadfield-Menell Associate Professor of Computer Science, MIT</p></div><div id="div_block-2374-1672-44" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sharon Li Associate Professor of Computer Science, University of Wisconsin Madison</p></div><div id="div_block-2374-1672-45" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Vael Gates Humans in Control</p></div><div id="div_block-2374-1672-46" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Deger Turan Metaculus</p></div><div id="div_block-2374-1672-47" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ed Newton-Rex CEO, Fairly Trained</p></div><div id="div_block-2374-1672-48" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alison Rice Managing Director, Design It For Us</p></div><div id="div_block-2374-1672-49" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brooke Istook Chief Impact Officer, Heat Initiative</p></div><div id="div_block-2374-1672-50" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Medlir Mema Founder and Director, AI Ethics and Governance Institute; Senior Fellow, Organized Intelligence</p></div><div id="div_block-2374-1672-51" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Vivian Dong Programs Director, Legal Advocates for Safe Science and Technology</p></div><div id="div_block-2374-1672-52" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tegan Maharaj Assistant Professor in Machine Learning, Mila</p></div><div id="div_block-2374-1672-53" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Krueger CEO, Evitable; Assistant Professor, University of Montreal, Mila</p></div><div id="div_block-2374-1672-54" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Roman Yampolskiy Professor, Computer Science and Engineering. Author, AI: Unexplainable, Unpredictable, Uncontrollable, UofL</p></div><div id="div_block-2374-1672-55" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Walter Scheirer Professor, Department of Computer Science and Engineering, University of Notre Dame</p></div><div id="div_block-2374-1672-56" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jillian Clare LA Board Member, Chair National Young Performer’s Committee, SAG-AFTRA</p></div><div id="div_block-2374-1672-57" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nick Smoke Actor, SAG-AFTRA, known for "The Social Network"</p></div><div id="div_block-2374-1672-58" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Karen A. Brown Filmmaker/Actor, SAG-AFTRA/StardustBlue Media</p></div><div id="div_block-2374-1672-59" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jesse Martinez Carlos Board Member, Los Angeles Local, SAG-AFTRA</p></div><div id="div_block-2374-1672-60" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Erik Passoja Co-Chair, LA New Technology Committee (2024-2025), SAG-AFTRA</p></div><div id="div_block-2374-1672-61" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Peggy Lane ORourke Actress, known from Seinfeld; SAG AFTRA Los Angeles Local Board Member, National Board Alternate</p></div><div id="div_block-2374-1672-62" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rob Drake Out There Pictures</p></div><div id="div_block-2374-1672-63" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joshua Hughes Greater Grace Christian Center</p></div><div id="div_block-2374-1672-64" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Cristine Legare UT Austin</p></div><div id="div_block-2374-1672-65" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mark Brakel Future of Life Institute</p></div><div id="div_block-2374-1672-66" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joe Allen Humans First</p></div><div id="div_block-2374-1672-67" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alexandra Tsalidis Future of Life Institute</p></div><div id="div_block-2374-1672-68" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>DZ Kalman Shalom Hartman Institute</p></div><div id="div_block-2374-1672-69" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Hsu Senior Director of Programs and Policy, Omidyar Network</p></div><div id="div_block-2374-1672-70" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Bobby Halick Hit Record</p></div><div id="div_block-2374-1672-71" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Justin Bullock Americans for Responsible Innovation</p></div><div id="div_block-2374-1672-72" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Oliver Stephenson Federation of American Scientists</p></div><div id="div_block-2374-1672-73" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Daniel Bring American Affairs</p></div><div id="div_block-2374-1672-74" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael Kleinman Future of Life Institute</p></div><div id="div_block-2374-1672-75" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Prof. Sandra M Faber Prof. Emerita, University of California, Santa Cruz</p></div><div id="div_block-2374-1672-76" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kate McCarthy Women's Media Center</p></div><div id="div_block-2374-1672-77" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>William Jones Future of Life Institute</p></div><div id="div_block-2374-1672-78" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Juliana Arnold Parent RISE!</p></div><div id="div_block-2374-1672-79" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Colin McGlynn Demand Progress Education Fund</p></div><div id="div_block-2374-1672-80" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rabbi Geoff Mitelman Sinai and Synapses</p></div><div id="div_block-2374-1672-81" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>John Unger FAITH Alliance—Fellowship Advancing Integrity in Technology &amp; Humanity</p></div><div id="div_block-2374-1672-82" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Haussler Professor, UC Santa Cruz</p></div><div id="div_block-2374-1672-83" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Beatrice Ekers Foresight Institute</p></div><div id="div_block-2374-1672-84" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Evan Davison Kotler Helena</p></div><div id="div_block-2374-1672-85" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ari Rosenthal Torchbearer Community</p></div><div id="div_block-2374-1672-86" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Connor Leahy ControlAI US</p></div><div id="div_block-2374-1672-87" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Fr. Michael Baggot Associate Professor of Bioethics, Pontifical Athenaeum Regina Apostolorum</p></div><div id="div_block-2374-1672-88" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sugheanmungol Sarin AI Safety Asia</p></div><div id="div_block-2374-1672-89" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Isabella Hampton Future of Life Institute</p></div><div id="div_block-2374-1672-90" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joshua Tan Public AI</p></div><div id="div_block-2374-1672-91" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jeremy Ornstein Center for AI Safety</p></div><div id="div_block-2374-1672-92" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Emma Ruby Sachs Eko</p></div><div id="div_block-2374-1672-93" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Philip Reiner Institute for Security and Technology</p></div><div id="div_block-2374-1672-94" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sam Hiner Young People's Alliance</p></div><div id="div_block-2374-1672-95" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lachlan Carroll Center for AI Safety</p></div><div id="div_block-2374-1672-96" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Riki Parikh Alliance for Secure AI</p></div><div id="div_block-2374-1672-97" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Christian F. Nunes President, Saving Ourselves Foundation Inc.</p></div><div id="div_block-2374-1672-98" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brian Boyd Future of Life Institute</p></div><div id="div_block-2374-1672-99" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Chase Hardin Future of Life Institute</p></div><div id="div_block-2374-1672-100" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dalia Hashad Future of Life Institute</p></div><div id="div_block-2374-1672-101" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Saheb Gulati Center for AI Safety</p></div><div id="div_block-2374-1672-102" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lucas Hansen CivAI</p></div><div id="div_block-2374-1672-103" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marianna Richardson G20 Interfaith Forum Association</p></div><div id="div_block-2374-1672-104" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sacha Hayworth Tech Oversight Project</p></div><div id="div_block-2374-1672-105" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Shana Mansbach Fathom</p></div><div id="div_block-2374-1672-106" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>John McElligott Servitium AI and Serviti Corp</p></div><div id="div_block-2374-1672-107" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Holly Elmore Pause AI</p></div><div id="div_block-2374-1672-108" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sander Volten Seismic Foundation</p></div><div id="div_block-2374-1672-109" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jaron Lanier Computer Scientist, Author</p></div><div id="div_block-2374-1672-110" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Valerie M. Hudson University Distinguished Professor, Texas A&amp;M University (and the Aegix Institute)</p></div><div id="div_block-2374-1672-111" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Maurine Molak Founder, David’s Legacy Foundation</p></div><div id="div_block-2374-1672-112" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ron Ivey Founder and CEO, Noēsis Collaborative</p></div><div id="div_block-2374-1672-113" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kirk Doran, Associate Professor of Economics Faculty, University of Notre Dame</p></div><div id="div_block-2374-1672-114" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Maria S. Eitel Founder, Plan A</p></div><div id="div_block-2374-1672-115" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Geoffrey Miller Associate Professor of Psychology, University of New Mexico</p></div><div id="div_block-2374-1672-116" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Camille Crittenden Executive Director, CITRIS and the Banatao Institute, University of California</p></div><div id="div_block-2374-1672-117" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joseph Vukov Associate Professor of Philosophy, Loyola University Chicago</p></div><div id="div_block-2374-1672-118" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Evan Harris Chancellor's Public Scholar, University of California, Berkeley</p></div><div id="div_block-2374-1672-119" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Zachary Davis Co-Founder, Faith Matters</p></div><div id="div_block-2374-1672-120" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Seán Coughlan Director, To Zero</p></div><div id="div_block-2374-1672-121" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Andrew Broz AI Research &amp; Strategy, Civilization Research Institute</p></div><div id="div_block-2374-1672-122" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Brenner Co-Founder and Board Chair Emeritus, AI and Faith</p></div><div id="div_block-2374-1672-123" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Emilia Ismael Head of Communications &amp; Operations, To Zero</p></div><div id="div_block-2374-1672-124" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Miki Yamashita Actor, SAG-AFTRA</p></div><div id="div_block-2374-1672-125" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Heather-Ashley Boyer Actor, Los Angeles Local Board Member, SAG-AFTRA</p></div><div id="div_block-2374-1672-126" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anamitra Deb SVP, Programs and Policy, Omidyar Network</p></div><div id="div_block-2374-1672-127" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Catherine Bracy CEO &amp; Founder, Tech Equity</p></div><div id="div_block-2374-1672-128" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marie Fink Stunt Coordinator, SAG-AFTRA, Los Angeles National Board Member</p></div><div id="div_block-2374-1672-129" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Wes McEnany Future of Life Institute</p></div><div id="div_block-2374-1672-130" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Konstantine Anthony Councilmember, City of Burbank</p></div><div id="div_block-2374-1672-131" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Taylor Jones Design &amp; Web Manager, Future of Life Institute</p></div><div id="div_block-2374-1672-132" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Stephen Casper AI researcher, Massachusetts Institute of Technology</p></div><div id="div_block-2374-1672-133" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kelly Kullberg American Association of Evangelicals, Veritas Forum</p></div><div id="div_block-2374-1672-134" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ben Cumming Director of Communications, Future of Life Institute</p></div><div id="div_block-2374-1672-135" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tristan Zucker Head of Operations, Humans First</p></div><div id="div_block-2374-1672-136" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nancy Green Saraisky Executive Director, Ethical Tech Project</p></div><div id="div_block-2374-1672-137" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anna Yelizarova Special Projects Lead, Future of Life Institute</p></div><div id="div_block-2374-1672-138" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>John Richard President, Essential Information</p></div><div id="div_block-2374-1672-139" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ryan T. Anderson President, The Ethics and Public Policy Center</p></div><div id="div_block-2374-1672-140" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Clare Morell Fellow, The Ethics and Public Policy Center</p></div><div id="div_block-2374-1672-141" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lisa Gilbert Co-President, Public Citizen</p></div><div id="div_block-2374-1672-142" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Robert Weissman Co-President, Public Citizen</p></div><div id="div_block-2374-1672-143" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Vivian Dong Programs Director, Legal Advocates for Safe Science and Technology</p></div><div id="div_block-2374-1672-144" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Teri Olle Vice President, Economic Security Project</p></div><div id="div_block-2374-1672-145" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brendan Bradley</p></div><div id="div_block-2374-1672-146" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michelle Margolis Librarian, Columbia University</p></div><div id="div_block-2374-1672-147" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Colin McGlynn AI Policy Advisor, Demand Progress Education Fund</p></div><div id="div_block-2374-1672-148" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sneha Revanur Founder &amp; President, Encode</p></div><div id="div_block-2374-1672-149" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Heather Booth Organizer</p></div><div id="div_block-2374-1672-150" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Robert Creamer Partner, Democracy Partners</p></div><div id="div_block-2374-1672-151" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brittney Gallagher Co-Founder, AI Objectives Institute</p></div><div id="div_block-2374-1672-152" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rania Batrice Strategist, Founder and President, Batrice and Associates</p></div><div id="div_block-2374-1672-153" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Leah Seligmann CEO, The B Team</p></div><div id="div_block-2374-1672-154" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Hon Jeff Denham US Representative- CA 10 (2011-2019)</p></div><div id="div_block-2374-1672-155" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Andrew Trask Executive Director, OpenMined</p></div><div id="div_block-2374-1672-156" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lawrence Lessig Roy L. Furman Professor of Law and Leadership, Harvard University</p></div><div id="div_block-2374-1672-157" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Xiaohu Zhu Founder, Center for Safe AGI</p></div><div id="div_block-2374-1672-158" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>John Sherman Executive Director, GuardRailNow/The AI Risk Network</p></div><div id="div_block-2374-1672-159" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Caleb Motupalli CEO, Agape Kingdom</p></div><div id="div_block-2374-1672-160" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr Luke McNally Senior Lecturer, University of Edinburgh</p></div><div id="div_block-2374-1672-161" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Audrey Tang Cyber Ambassador, Taiwan</p></div><div id="div_block-2374-1672-162" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mark Gubrud, PhD</p></div><div id="div_block-2374-1672-163" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Felix De Simone Organizing Director, PauseAI US</p></div><div id="div_block-2374-1672-164" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kevin Lotto AI Existential Risk Advocate, Torchbearer Community</p></div><div id="div_block-2374-1672-165" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Wesley H. Holliday Professor of Philosophy, University of California, Berkeley</p></div><div id="div_block-2374-1672-166" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Roger Kirkness CEO, Convictional, Inc.</p></div><div id="div_block-2374-1672-167" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael Huang Co-Director, PauseAI Australia</p></div><div id="div_block-2374-1672-168" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Maggie Munro Communications Strategist, Future of Life Institute</p></div><div id="div_block-2374-1672-169" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lindsay Langenhoven Freelance responsible tech writer</p></div><div id="div_block-2374-1672-170" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Geoffrey Martin Odlum President, Odlum Global Strategies</p></div><div id="div_block-2374-1672-171" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Adam McCabe Head of Research, Convictional</p></div><div id="div_block-2374-1672-172" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Erik Otto Managing Director, Ethagi Inc.</p></div><div id="div_block-2374-1672-173" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anna Hehir Head of Military AI Governance, Future of Life Institute</p></div><div id="div_block-2374-1672-174" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Siliconversations AI Safety YouTuber</p></div><div id="div_block-2374-1672-175" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Audrey Mocle Executive Director, Open MIC (Open Media and Information Companies Initiative)</p></div><div id="div_block-2374-1672-176" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mark Jerusalem Researcher in international AI strategy, Independent</p></div><div id="div_block-2374-1672-177" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Gabriele Sarti Postdoctoral Researcher, Norhteastern University</p></div><div id="div_block-2374-1672-178" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brett Cooper Fundraising Copywriter, JB Cooper LLC</p></div><div id="div_block-2374-1672-179" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Yeshodhara Baskaran Founder, ZuGrama</p></div><div id="div_block-2374-1672-180" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Guru Medasani Founder &amp; CEO, Ridy</p></div><div id="div_block-2374-1672-181" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Shadi Bartsch Professor, Forum for Integrated Research</p></div><div id="div_block-2374-1672-182" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Louise Graham FRSA Founder, The Unwritten Future</p></div><div id="div_block-2374-1672-183" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Prof. Piotr Sankowski Director, IDEAS Research Institute</p></div><div id="div_block-2374-1672-184" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>dr. Jeroen Franse AI Governance Advisor, AI Point EU</p></div><div id="div_block-2374-1672-185" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Patrick Hoang Student, Texas A&amp;M University</p></div><div id="div_block-2374-1672-186" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sun Gyoo Kang Founder, Law &amp; Ethics in Tech</p></div><div id="div_block-2374-1672-187" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Carlos Javier Regazzoni Director, Committee in Global Health and Human Security, Argentine Council on Foreign Relations (CARI)</p></div><div id="div_block-2374-1672-188" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jimena Sofia Viveros Alvarez President, The HumAIne Foundation</p></div><div id="div_block-2374-1672-189" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ewan Morrison Author</p></div><div id="div_block-2374-1672-190" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ori Nagel Producer, Doom Debates</p></div><div id="div_block-2374-1672-191" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marc Barnes Editor, New Polity Magazine</p></div><div id="div_block-2374-1672-192" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Daniel Koch Assistant Professor, University of Manitoba, Canada</p></div><div id="div_block-2374-1672-193" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Andrea Fiegl Senior Policy Director, Media and Technology, Common Cause</p></div><div id="div_block-2374-1672-194" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anderson Rocha Tavares Professor, Universidade Federal do Rio Grande do Sul</p></div><div id="div_block-2374-1672-195" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Hunter Lees Graduate Student, Lipscomb University</p></div><div id="div_block-2374-1672-196" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Matthew Chequers Applied AI R&amp;D, Convictional</p></div><div id="div_block-2374-1672-197" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Samuel Thibault Professor, University of Bordeaux</p></div><div id="div_block-2374-1672-198" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joshua Cohen Distinguished Senior Fellow in Law, Philosophy, and Political Science, University of California, Berkeley</p></div><div id="div_block-2374-1672-199" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ariartry Founder, The Altern Research Collective for Brains, Minds &amp; Machines</p></div><div id="div_block-2374-1672-200" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mikita Belahlazau Software engineer, Waymo</p></div><div id="div_block-2374-1672-201" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Lucas Mello Schnorr Associate Professor, UFRGS</p></div><div id="div_block-2374-1672-202" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lauren Mecca Founder, Tech/ish</p></div><div id="div_block-2374-1672-203" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Amber Scorah Cofounder, Author, Psst.org</p></div><div id="div_block-2374-1672-204" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Amir Banifatemi Co-Founder, AI Commons</p></div><div id="div_block-2374-1672-205" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Álvaro Guglielmin Becker Student, UFRGS</p></div><div id="div_block-2374-1672-206" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marcelo Soares Pimenta Full professor, UFRGS</p></div><div id="div_block-2374-1672-207" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Félix Pharand-Deschênes Director, Globaïa</p></div><div id="div_block-2374-1672-208" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joshua Anderson Founder, Cantaloupe AI</p></div><div id="div_block-2374-1672-209" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Wood Chair, London Futurists</p></div><div id="div_block-2374-1672-210" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jeannie Joshi Brand Innovation</p></div><div id="div_block-2374-1672-211" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ayoze García González National leader, Spain, PauseAI</p></div><div id="div_block-2374-1672-212" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ron Bodkin CEO CEO, ChainML, Inc.</p></div><div id="div_block-2374-1672-213" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Iago Tonello Student, Federal University of Rio Grande do Sul</p></div><div id="div_block-2374-1672-214" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Glen Webster Board Director, Meridian Cambridge</p></div><div id="div_block-2374-1672-215" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Vicente Veiga Student, UFRGS</p></div><div id="div_block-2374-1672-216" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Yixiong Hao Co-director, AI Safety Initiative at Georgia Tech</p></div><div id="div_block-2374-1672-217" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rodrigo Cavalcanti AI Governance Consultant, Analogik</p></div><div id="div_block-2374-1672-218" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mustafa Saeed Co-Founder &amp; CEO, Luella</p></div><div id="div_block-2374-1672-219" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Manuel M. Oliveira, PhD Full Professor of Computer Science, UFRGS</p></div><div id="div_block-2374-1672-220" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Simon Skade Co-Lead, PauseAI Germany</p></div><div id="div_block-2374-1672-221" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alon Torres AI Safety Advocate, Torchbearer Community, International Association for Safe &amp; Ethical AI</p></div><div id="div_block-2374-1672-222" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joel Luís Carbonera, PhD Professor, Federal University of Rio Grande do Sul (UFRGS)</p></div><div id="div_block-2374-1672-223" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Benjamin Dreyfus Instructional Professor of Physics, George Mason University</p></div><div id="div_block-2374-1672-224" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rafael Rost Sofware Engineer, SAP</p></div><div id="div_block-2374-1672-225" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nivedita Sharma Business Management Consultant</p></div><div id="div_block-2374-1672-226" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Risto Uuk Visiting Researcher, London School of Economics</p></div><div id="div_block-2374-1672-227" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Doctor Caleb Bernacchio Legendre-Soulé Chair in Business Ethics, Associate Professor of Management &amp; Faculty Director of the Center for Ethics and Economic Justice at Loyola University New Orleans, Loyola University New Orleans</p></div><div id="div_block-2374-1672-228" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Timothy B. Elder, PhD Research Associate, The Dartmouth Institute, Geisel School of Medicine, Dartmouth College</p></div><div id="div_block-2374-1672-229" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Akbar Tri Laksana Founder, Athena© Organization Labs</p></div><div id="div_block-2374-1672-230" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jackie Hart CEO, Exponential Infrastructure for Coordination</p></div><div id="div_block-2374-1672-231" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sophia Ward People Services</p></div><div id="div_block-2374-1672-232" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Robert Muggah Co-founder, Igarape Institute</p></div><div id="div_block-2374-1672-233" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Fredy Enrique Mena Andrade CTO, Simuliz Interactive S.A.S</p></div><div id="div_block-2374-1672-234" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nathan Metzger Volunteer and Board Member, PauseAI US</p></div><div id="div_block-2374-1672-235" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Daniel Gerritzen Science writer, author, Forschungsnetzwerk Extraterrestrische Intelligenz (Extraterrestrial Intelligence Research Network)</p></div><div id="div_block-2374-1672-236" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael Walker Author</p></div><div id="div_block-2374-1672-237" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rufus Pollock CEO, Life Itself</p></div><div id="div_block-2374-1672-238" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dan Lipworth Founder, True North Tutors</p></div><div id="div_block-2374-1672-239" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Heather-Ashley Boyer Actor, Los Angeles Local Board Member, SAG-AFTRA</p></div><div id="div_block-2374-1672-240" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mr. Bennett Iorio President, Geopolitical Insight and Education Foundation</p></div><div id="div_block-2374-1672-241" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ilia Grom Member of the Administrative Council, Art-Labyrinth</p></div><div id="div_block-2374-1672-242" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rafael Gold Founding Partner, The Israeli Association for Ethics in AI</p></div><div id="div_block-2374-1672-243" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Pedro Javier Martos Velasco Principal Engineer, The Workshop</p></div><div id="div_block-2374-1672-244" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Izolda Dr. Takacs International lawyer, Norwegian Centre for Human Right</p></div><div id="div_block-2374-1672-245" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Saimir Baci Engineer CTO, Co-Founder, Augmentifai</p></div><div id="div_block-2374-1672-246" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lionel Levine Professor of Mathematics, Cornell University</p></div><div id="div_block-2374-1672-247" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Professor Albert Ossó Castillon Professor, University of Graz (Austria)</p></div><div id="div_block-2374-1672-248" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Leonardo Holtz de Oliveira AI Researcher, SENAI Institute of Innovation</p></div><div id="div_block-2374-1672-249" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Grace Roberts</p></div><div id="div_block-2374-1672-250" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr Tony Carden Adjunct Researcher, University of the Sunshine Coast</p></div><div id="div_block-2374-1672-251" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Faisal S. AI Audit, AuditPartners</p></div><div id="div_block-2374-1672-252" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Daniel Yokomizo Human Being, Humanity</p></div><div id="div_block-2374-1672-253" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>William Louth CTO, Humainary</p></div><div id="div_block-2374-1672-254" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Steven Adger Sys Admin/Web Dev, Independent Contractor</p></div><div id="div_block-2374-1672-255" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kyle Brockley Founder, BrockboxLLC</p></div><div id="div_block-2374-1672-256" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Vanessa Chester SAG-AFTRA LA Local Board Member, Actress most known for The Lost World: Jurassic Park, Harriet the Spy</p></div><div id="div_block-2374-1672-257" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ícaro Neri Pereira de Souza Researcher/Geographer, UFMG/CEFET-MG</p></div><div id="div_block-2374-1672-258" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>John Weldon Clinical A.I. Director, Deciphex</p></div><div id="div_block-2374-1672-259" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Shane Cannon Psychotherapist</p></div><div id="div_block-2374-1672-260" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Benjamin Shimabukuro Cogito Systems Engineer, Epic</p></div><div id="div_block-2374-1672-261" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nathan Hammond Founder, The Fellowship of Sovereign Consciousness</p></div><div id="div_block-2374-1672-262" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Hocine Sahnoun Volonteer, Teacher</p></div><div id="div_block-2374-1672-263" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Yaniv Ben Zriham VP R&amp;D, Equashield</p></div><div id="div_block-2374-1672-264" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mr Matthew Kilkenny Founder, Ethicalainow.org</p></div><div id="div_block-2374-1672-265" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Paul Dos Santos Group Head of Information Security, SG Fleet</p></div><div id="div_block-2374-1672-266" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jon Salisbury CEO, Nexigen</p></div><div id="div_block-2374-1672-267" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mr. Vlad Suheschi Photographer, sportphotoevents.com</p></div><div id="div_block-2374-1672-268" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Edson Prestes Full Professor, Federal University of Rio Grande do Sul</p></div><div id="div_block-2374-1672-269" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Santiago J. Isbert Perlender CEO - Author, CINME</p></div><div id="div_block-2374-1672-270" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Andrew Arkins</p></div><div id="div_block-2374-1672-271" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kevin Russi Senior Partner, RUSSI + PARTNER</p></div><div id="div_block-2374-1672-272" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Cristóbal Rodríguez-Montoya Professor, Pontificia Universidad Católica Madre y Maestra</p></div><div id="div_block-2374-1672-273" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Christopher Wright CEO, The AI Trust Council</p></div><div id="div_block-2374-1672-274" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Clay Jackson</p></div><div id="div_block-2374-1672-275" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jonathan Murphy</p></div><div id="div_block-2374-1672-276" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ian Bassin Co Founder and Executive Director, Protect Democracy</p></div><div id="div_block-2374-1672-277" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Max Winga Policy Analyst, ControlAI</p></div><div id="div_block-2374-1672-278" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Roger Abbiss Founder, Occupy Earth</p></div><div id="div_block-2374-1672-279" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marc Carter Chief, IT Business Management Division, US Army</p></div><div id="div_block-2374-1672-280" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Cyrus Hodes Founder, AI Safety Connect</p></div><div id="div_block-2374-1672-281" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael R Scheessele Professor Emeritus of Computer Science and Psychology, Indiana University South Bend</p></div><div id="div_block-2374-1672-282" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Steven Damian Imparl Independent scholar, lawyer, AI engineer, and philosopher, Steven Damian Imparl</p></div><div id="div_block-2374-1672-283" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anthony Bailey Software developer, Pause AI</p></div><div id="div_block-2374-1672-284" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Michael R Scheessele Professor Emeritus of Computer Science and Psychology, Indiana University South Bend</p></div><div id="div_block-2374-1672-285" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dmytro Hrybach Product Manager, Business</p></div><div id="div_block-2374-1672-286" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>SAAKSHAR DUGGAL AI law Expert, AI Law Hub</p></div><div id="div_block-2374-1672-287" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ionut Vasile Cyber Security Consultant, Independent Consultant</p></div><div id="div_block-2374-1672-288" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Luke Housego Board Member, Decentralised Human Architecture Foundation</p></div><div id="div_block-2374-1672-289" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mohamed ElBendary AI Governance Researcher, Independent</p></div><div id="div_block-2374-1672-290" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alexander McCoy Senior Movement Staff, Humans First</p></div><div id="div_block-2374-1672-291" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Bill Crandall Artist and Arts Educator, Viaduct Arts</p></div><div id="div_block-2374-1672-292" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. George Tilesch President, PHI INSTITUTE for Augmented Intelligence</p></div><div id="div_block-2374-1672-293" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mridutpal Bhattacharyya Chief Policy Advisor, Indian Society of Artificial Intelligence and Law</p></div><div id="div_block-2374-1672-294" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Abhivardhan Founder, Indic Pacific</p></div><div id="div_block-2374-1672-295" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lucas Chu Founding Architect, HF0</p></div><div id="div_block-2374-1672-296" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Gordon Seidoh Worley Director of Research, Phenomenological AI Safety Research Institute</p></div><div id="div_block-2374-1672-297" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Barbara Anna Zielonka Educator, Nannestad vgs</p></div><div id="div_block-2374-1672-298" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Saeed K. Al Dhaheri Director, Center of Futures Studies, University of Dubai</p></div><div id="div_block-2374-1672-299" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Paul Prinsloo Professor Extraordinaire, University of South Africa (Unisa)</p></div><div id="div_block-2374-1672-300" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sophia Steen Analyst, Alignmint</p></div><div id="div_block-2374-1672-301" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nikita Yampolski Co-Founder, CTO &amp; CPO, One Mental Hub</p></div><div id="div_block-2374-1672-302" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Simon Bramwell Facilitator, X-AEGIS</p></div><div id="div_block-2374-1672-303" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Adrian Brown Chief Executive, Windfall Trust</p></div><div id="div_block-2374-1672-304" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Olaf Witkowski Director, Cross Labs</p></div><div id="div_block-2374-1672-305" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Karl Markus Villemson Grant Funding and Project Manager, H2Electro</p></div><div id="div_block-2374-1672-306" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joe Cozens Teacher of AI &amp; Transformation, University of Oxford</p></div><div id="div_block-2374-1672-307" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Henry Ward AI Engineer, Freelance</p></div><div id="div_block-2374-1672-308" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Aleksandr Popov</p></div><div id="div_block-2374-1672-309" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr Hadyn Williams Fmr CEO British Association for Counselling &amp; Psychotherapy, Executive Consultant</p></div><div id="div_block-2374-1672-310" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Christos Theodoropoulos AI Solutions Architect, Qity</p></div><div id="div_block-2374-1672-311" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Cristiano De Mei Writer and AI expert, Fideuram</p></div><div id="div_block-2374-1672-312" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Laura Maria Kull Co-Director, Effective Altruism Estonia</p></div><div id="div_block-2374-1672-313" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>James Wilson Global AI Ethicist, Capgemini</p></div><div id="div_block-2374-1672-314" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alvaro Sanchez, PhD Physicist and AI safety researcher, Independent Researcher</p></div><div id="div_block-2374-1672-315" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tara Steele Director, The Safe AI for Children Alliance</p></div><div id="div_block-2374-1672-316" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Erik Arnberg CEO, Vocitas AB</p></div><div id="div_block-2374-1672-317" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Raja Chatila Professor Emeritus, Sorbonne University, Paris</p></div><div id="div_block-2374-1672-318" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Roberto Cerina Assistant Professor in Social and Humane AI, Institute for Logic, Language and Computation, University of Amsterdam</p></div><div id="div_block-2374-1672-319" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Pauline Delorme UX Strategist, Softeam</p></div><div id="div_block-2374-1672-320" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Roberto Cerina Assistant Professor in Social and Humane AI, Institute for Logic, Language and Computation, University of Amsterdam</p></div><div id="div_block-2374-1672-321" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr Michael Strange Researcher, Malmö University</p></div><div id="div_block-2374-1672-322" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Izolda Dr. Takacs International lawyer, Norwegian Centre for Human Right</p></div><div id="div_block-2374-1672-323" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jochen Dullenkopf CEO, RevenueWings - Online Marketing Solutions Inc.</p></div><div id="div_block-2374-1672-324" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Manheim Director of Policy and Research, Alter.org.il</p></div><div id="div_block-2374-1672-325" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Roland Millare, STD Vice President of Curriculum, Director of Clergy Initiatives, St. John Paul II Foundation</p></div><div id="div_block-2374-1672-326" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Corinne Thomas AI Commercial Adoption &amp; Governance, Ethical Sales Ltd</p></div><div id="div_block-2374-1672-327" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Irina Monica Buruiană Systemic Designer and Psychologist, Ultreiacamino</p></div><div id="div_block-2374-1672-328" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sheila Pinheiro Nainkin Head of Fractional Fraud and Risk, Pinheirorisk.com</p></div><div id="div_block-2374-1672-329" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rafael Gold Founding Partner, The Israeli Association for Ethics in Artificial Intelligence</p></div><div id="div_block-2374-1672-330" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ilia Grom Member of the Administrative Council, Art-Labyrinth</p></div><div id="div_block-2374-1672-331" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Erich Mische CEO, SAVE-Suicide Awareness Voices of Education</p></div><div id="div_block-2374-1672-332" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alain Létourneau Professor, practical philosophy, Université de Sherbrooke</p></div><div id="div_block-2374-1672-333" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Max Blair Associate Principal Oboe, Pittsburgh Symphony</p></div><div id="div_block-2374-1672-334" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ryan Davis Founder &amp; CEO, People First</p></div><div id="div_block-2374-1672-335" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Raluca Spataru PauseAI Romania Country Lead, Lawyer, PhD Student, PauseAI</p></div><div id="div_block-2374-1672-336" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Peter A. Jensen CEO, SAFE AI Forever Inc.</p></div><div id="div_block-2374-1672-337" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Elena Gallina Artist, E Gallina Art</p></div><div id="div_block-2374-1672-338" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Laurens Martens Senior Art Director, AKQA</p></div><div id="div_block-2374-1672-339" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ayoub Ibnoulfassih Journalist, L'angle</p></div><div id="div_block-2374-1672-340" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Philip Trippenbach Strategy Director, Seismic Foundation</p></div><div id="div_block-2374-1672-341" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Martin Quinson Professor, ENS Rennes</p></div><div id="div_block-2374-1672-342" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dirk Friedrich Founder, Five Intelligences Alliance</p></div><div id="div_block-2374-1672-343" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tomas Prajzler CEO, Talentor CZ</p></div><div id="div_block-2374-1672-344" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rufo Guerreschi President, Coalition for a Baruch Plan for AI</p></div><div id="div_block-2374-1672-345" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Sachs Assistant Professor, Icahn School of Medicine at Mount Sinai</p></div><div id="div_block-2374-1672-346" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Octavian M. Machidon Assistant professor, University of Ljubljana, Faculty of Computer and Information Science</p></div><div id="div_block-2374-1672-347" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Daniel Girshovich Human, TFH</p></div><div id="div_block-2374-1672-348" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Julia da Rocha Junqueira PHD Student, UFRGS</p></div><div id="div_block-2374-1672-349" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Bernhard Braun Scientific Associate, Federal Highway and Transport Research Institute Germany</p></div><div id="div_block-2374-1672-350" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Remmelt Ellen Coordinator, AI Safety Camp</p></div><div id="div_block-2374-1672-351" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rolland Lucas Owner / Business Analyst, BrixTec Web Soutions</p></div><div id="div_block-2374-1672-352" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Luka Stevanovic Software Engineer, Connect The Dots</p></div><div id="div_block-2374-1672-353" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kaarel Hänni AI Safety Researcher, Independent</p></div><div id="div_block-2374-1672-354" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lucas E. Wall CEO &amp; Founder, Almma.AI</p></div><div id="div_block-2374-1672-355" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dino Lortie</p></div><div id="div_block-2374-1672-356" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Steven Potaczek Professor of Commercial Music, Samford University</p></div><div id="div_block-2374-1672-357" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Gordon Montgomery Researcher, Sofia.edu</p></div><div id="div_block-2374-1672-358" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ann Bender Dalhäll Owner, Northbound group</p></div><div id="div_block-2374-1672-359" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jordan Panayotov Founder, Creator of The Panayotov Matrix, superior tool which ensures that AI systems are truly Human-Centric, fully inline with The Pro-Human Declaration, Independent Centre for Analysis &amp; Research of Economies</p></div><div id="div_block-2374-1672-360" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Svilen Kondakov Substitute Teacher</p></div><div id="div_block-2374-1672-361" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Ariel Agor Operational Ontologist, Agor AI Advisory</p></div><div id="div_block-2374-1672-362" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Martin Dinov CTO, Maaind/Lifefire</p></div><div id="div_block-2374-1672-363" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Piotr Sankowski Director, IDEAS Research Institute</p></div><div id="div_block-2374-1672-364" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jennifer Gibson Executive Director, Psst.org</p></div><div id="div_block-2374-1672-365" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joseph Gelfer Organiser, Our Fair Future</p></div><div id="div_block-2374-1672-366" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>James Norris Founder &amp; Executive Director, Center for Existential Safety</p></div><div id="div_block-2374-1672-367" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Marie Lotto</p></div><div id="div_block-2374-1672-368" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Gabriel Barbosa Taffarel Undergraduated, UFRGS</p></div><div id="div_block-2374-1672-369" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr Michael Hall Senior Lecturer in Education, University of Winchester</p></div><div id="div_block-2374-1672-370" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Lovkush Agarwal Research Manager, MATS</p></div><div id="div_block-2374-1672-371" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Gianluca Bontempi Professor of Machine Learning, Université Libre de Bruxelles</p></div><div id="div_block-2374-1672-372" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jaedon Satchell AI Developer, Cognizant</p></div><div id="div_block-2374-1672-373" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tobias Fritz Assistant Professor, University of Innsbruck</p></div><div id="div_block-2374-1672-374" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jeremiah Wesley Templeman Harding Postgraduate, London School of Economics and Political Science</p></div><div id="div_block-2374-1672-375" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Peter Joyce MD &amp; CAIO, Grand Challenge AI</p></div><div id="div_block-2374-1672-376" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>José González Artist, José González</p></div><div id="div_block-2374-1672-377" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Chris Scammell CEO, Buddhism &amp; AI Initiative</p></div><div id="div_block-2374-1672-378" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Torbjörn Lundh Professor, Chalmers University of Technology</p></div><div id="div_block-2374-1672-379" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Steven Engler Professor of Religious Studies, Mount Royal University</p></div><div id="div_block-2374-1672-380" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Kyle Kahl Healer</p></div><div id="div_block-2374-1672-381" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rabbi Daniel Levin Senior Rabbi, Temple Beth El of Boca Raton</p></div><div id="div_block-2374-1672-382" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David S Snyder, M.D. Retired Physician, City of Hope Cancer Center</p></div><div id="div_block-2374-1672-383" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alan Sousie</p></div><div id="div_block-2374-1672-384" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Patricia Palmer Retired legal marketing director</p></div><div id="div_block-2374-1672-385" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Elena Chirila Commercial Director, B+N Integrated Facility Services</p></div><div id="div_block-2374-1672-386" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Anderson Maciel Professor, UFRGS</p></div><div id="div_block-2374-1672-387" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mark Andrew Kordic Podcast Host, Advancing Your Vision</p></div><div id="div_block-2374-1672-388" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Janet Frances Howard</p></div><div id="div_block-2374-1672-389" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jeff Cooper Executive Director, Approachable Intelligence Research Foundation</p></div><div id="div_block-2374-1672-390" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joshua Kauffman Founder, Wisdom VC</p></div><div id="div_block-2374-1672-391" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>MaryAnn Derrick-Green Owner, Studiomadtulsa</p></div><div id="div_block-2374-1672-392" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Joan Williamson-Kelly</p></div><div id="div_block-2374-1672-393" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>José Jaime Villalobos Ruiz Multilateral Governance Lead, Future of Life Institute</p></div><div id="div_block-2374-1672-394" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>David Markowitz Psychologist</p></div><div id="div_block-2374-1672-395" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Nate Hake Founder, Travel Lemming</p></div><div id="div_block-2374-1672-396" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>John Mason</p></div><div id="div_block-2374-1672-397" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Japhet Student, Centre for Alternative Technology</p></div><div id="div_block-2374-1672-398" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Karl von Wendt Writer, Independent</p></div><div id="div_block-2374-1672-399" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Armando di Matteo Researcher, Istituto Nazionale di Fisica Nucleare, Sezione di Torino</p></div><div id="div_block-2374-1672-400" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Naiyarah Hussain Co-founder, AI Safety UAE</p></div><div id="div_block-2374-1672-401" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jovin Cronin-Wilesmith Partner, Celium Group</p></div><div id="div_block-2374-1672-402" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Alexandre Ngau AI Strategy Consultant, Sia</p></div><div id="div_block-2374-1672-403" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Emily Boddy Co-Lead, Smartphone Free Childhood US</p></div><div id="div_block-2374-1672-404" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Mateusz Bagiński Researcher, AFFINE</p></div><div id="div_block-2374-1672-405" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rabbi Josh Feigelson President &amp; CEO, Institute for Jewish Spirituality</p></div><div id="div_block-2374-1672-406" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Antonis Polykratis Software Engineer</p></div><div id="div_block-2374-1672-407" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Andrew Shanahan Editor, Future of Life Institute</p></div><div id="div_block-2374-1672-408" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Faheem Salman Yunus CTO &amp; Co founder, Nuvint Dynamics</p></div><div id="div_block-2374-1672-409" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Olin Thakur Co-Founder, Techplomacy Foundation</p></div><div id="div_block-2374-1672-410" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Vicente Pinto Citizen, TorchBearer Comunnity</p></div><div id="div_block-2374-1672-411" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Harish Mehta Chairman, Onward</p></div><div id="div_block-2374-1672-412" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Lesaun Harvey Founder, Technological Liberty, inc</p></div><div id="div_block-2374-1672-413" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Krystal Jackson Non-Resident Research Fellow, UC Berkeley, Center for Long-Term Cybersecurity</p></div><div id="div_block-2374-1672-414" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Robert Rand Assistant Professor of Computer Science, University of Chicago</p></div><div id="div_block-2374-1672-415" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Joseph Thornton Candidate, Thornton for Florida House District 10</p></div><div id="div_block-2374-1672-416" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Allan Brooks Community Manager, The Human Line Project</p></div><div id="div_block-2374-1672-417" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Shantanu Ghosh, Ph.D. Professor, Amity University</p></div><div id="div_block-2374-1672-418" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sreejith Sreedharan Author - Future of Work, Future of Work AI Labs</p></div><div id="div_block-2374-1672-419" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Paul Hebert Founder, AI Recovery Collective</p></div><div id="div_block-2374-1672-420" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Adrian A CTO, PT. Ksatria Mitra S</p></div><div id="div_block-2374-1672-421" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Rabbi Neal Gold Founder and Director, A Tree with Roots</p></div><div id="div_block-2374-1672-422" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Pedro Ávila Lecturer, Columbia University</p></div><div id="div_block-2374-1672-423" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Aiden Kim Researcher, Center for AI Safety</p></div><div id="div_block-2374-1672-424" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>William Baird UK Board Member, PauseAI</p></div><div id="div_block-2374-1672-425" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jose Cesar ‘Zeca’ Martins Leader, Derrubando Muros</p></div><div id="div_block-2374-1672-426" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Avinash Tax Consultant, KPMG</p></div><div id="div_block-2374-1672-427" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Sari Katariina Riippi AI engineer, Freelance</p></div><div id="div_block-2374-1672-428" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Charbel-Raphael Segerie Executive Director, CeSIA - French Center for AI Safety</p></div><div id="div_block-2374-1672-429" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Tunde Aideyan, PhD Instructor, Northeastern University</p></div><div id="div_block-2374-1672-430" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>JB Herrera Founder/CEO, SynergiAI</p></div><div id="div_block-2374-1672-431" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Brendan O’Donoghue Managing Director, Artificial Observer Limited</p></div><div id="div_block-2374-1672-432" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Aidar Toktargazin Student, Nazarbayev University</p></div><div id="div_block-2374-1672-433" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Matteo Mastracci Senior Legal Officer, Italian Ministry of Education and Merit</p></div><div id="div_block-2374-1672-434" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Luiza Jarovsky CEO, AI, Tech &amp; Privacy Academy</p></div><div id="div_block-2374-1672-435" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Xavier de Souza Briggs Senior Fellow, The Brookings Institution</p></div><div id="div_block-2374-1672-436" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Jake Hirsch-Allen Public AI Fellow and Director Partnerships and Advocacy, The Dais</p></div><div id="div_block-2374-1672-437" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Karine Landry Teacher, Cégep de Valleyfield</p></div><div id="div_block-2374-1672-438" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Matthew Prewitt President, RadicalxChange Foundation</p></div><div id="div_block-2374-1672-439" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Karl Berzins President, FAR.AI</p></div><div id="div_block-2374-1672-440" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Timothy O’Donnell Professor, McGill University</p></div><div id="div_block-2374-1672-441" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Dr. Sian Tsuei Clinical Assistant Professor, UBC</p></div><div id="div_block-2374-1672-442" class="ct-div-block signatory-list-item oxy-rich-text text--line-height-s" data-id="div_block-2374-1672"><p>Samuel Robson Student, UC Berkeley</p></div></div></div><div tabindex="-1" class="oxy-modal-backdrop ct-modal modals-homepage c3" data-trigger="user_clicks_element" data-trigger-selector="#span-27-1676-2" data-trigger-time="5" data-trigger-time-unit="seconds" data-close-automatically="no" data-close-after-time="10" data-close-after-time-unit="seconds" data-trigger_scroll_amount="50" data-trigger_scroll_direction="down" data-scroll_to_selector="" data-time_inactive="60" data-time-inactive-unit="seconds" data-number_of_clicks="3" data-close_on_esc="on" data-number_of_page_views="3" data-close-after-form-submit="no" data-open-again="always_show" data-open-again-after-days="3"><a id="link_button-2496-9" class="ct-link-button oxy-close-modal" href="http://" target="_self">Close</a><div id="_rich_text-2495-9" class="oxy-rich-text"><p><em><strong>AFL-CIO Tech Institute | March 4, 2026</strong></em></p><p>The AFL-CIO Tech Institute supports the spirit of the Principles of the Pro-Human AI Declaration, shares the conviction that AI must serve people, not the reverse, and affirms the need for:</p><ol><li>Keeping Humans in Charge</li>
<li>Avoiding Concentration of Power</li>
<li>Protecting the Human Experience</li>
<li>Human Agency and Liberty</li>
<li>Responsibility and Accountability for AI Companies</li>
</ol><p>Additionally, we believe that work is an essential element of human dignity, and must be central to any policy debate around AI. The <a href="https://aflcio.org/sites/default/files/2025-10/Final%20for%20Website%20-%20ARTIFICIAL%20INTELLIGENCE%20Principles%20to%20Protect%20Workers_10.15.25_0.pdf" target="_blank" rel="noopener">AFL-CIO’s AI Principles</a> center workers and ensure that the benefits of new technologies are widely shared and do not lead to dangerous, discriminatory and anti-worker outcomes. It is important that we do not concede to the notion that AI adoption is inevitable. We must recognize the limitations that exist for this technology, which does not supersede the knowledge, experience, and hands-on work required for many private and public sector jobs. Workers must have a hand in shaping when and how the technology is developed and deployed to ensure that it improves society, delivers public benefits, and does not lead to the displacement of workers. As rapid technological change is poised to define the future of millions of jobs, it is essential that federal, state, and local leaders champion policies that:</p><ol><li>Strengthen labor rights and broaden opportunities for collective bargaining</li>
<li>Advance guardrails against harmful uses of AI in the workplace</li>
<li>Support and promote copyright and intellectual property protections</li>
<li>Develop a worker-centered workforce development and training system</li>
<li>Institutionalize worker voice within AI R&amp;D</li>
<li>Require transparency and accountability in AI applications</li>
<li>Model best practices for AI use with government procurement</li>
<li>Protect workers’ civil rights and uphold democratic integrity</li>
</ol><p>The AFL-CIO has adopted principles for fair, safe, responsible and worker-centered AI. We choose a future where progress and opportunity benefit everyone, and where AI isn’t used against us or to weaken the protections that a fair and thriving democracy demands.</p></div></div></div></div></section><section id="section-2432-9" class="ct-section"><div class="ct-section-inner-wrap ct-div-block"><p>The Pro-Human AI Declaration</p><p>March 2026</p></div></section>]]></description>
      <link>https://humanstatement.org/</link>
      <guid>https://humanstatement.org/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Introducing GPT-5.4 | OpenAI]]></title>
      <description><![CDATA[]]></description>
      <link>https://openai.com/index/introducing-gpt-5-4/</link>
      <guid>https://openai.com/index/introducing-gpt-5-4/</guid>
      <pubDate>Wed, 11 Mar 2026 06:47:00 +0100</pubDate>
    </item>
  </channel>
</rss>
