<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stephan Miller</title>
    <description>The latest articles on DEV Community by Stephan Miller (@eristoddle).</description>
    <link>https://dev.to/eristoddle</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F18795%2F5f6c41b8-6033-4887-937a-2ebdfe623d2e.jpeg</url>
      <title>DEV Community: Stephan Miller</title>
      <link>https://dev.to/eristoddle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eristoddle"/>
    <language>en</language>
    <item>
      <title>Your Ebook Library Beats the Web for Research, and Your Coding Agent Can Search It Without RAG</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Wed, 11 Nov 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/your-ebook-library-beats-the-web-for-research-and-your-coding-agent-can-search-it-without-rag-3f39</link>
      <guid>https://dev.to/eristoddle/your-ebook-library-beats-the-web-for-research-and-your-coding-agent-can-search-it-without-rag-3f39</guid>
      <description>&lt;p&gt;Ask a coding agent to research “how does X actually work” and it will use web search and find some blog posts about X. Those blog posts are summaries of a book somebody wrote about X. Sometimes they’re summaries of other blog posts that summarized the book. For a settled, conceptual question, that summary-of-a-summary chain is all there is.&lt;/p&gt;

&lt;p&gt;I own about 30k ebooks. Somewhere in that collection, a writer spent 300 pages on the topic a blog post only has 800 words on. So I built a skill, &lt;code&gt;ebook-research&lt;/code&gt;, that lets my agent find the book, find the chapter, get the text, and cite it. This week I moved it into my public &lt;a href="https://github.com/eristoddle/agent-skills" rel="noopener noreferrer"&gt;agent-skills repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You might assume it’s a RAG project. Instead, it’s a full-text index that has been around for over 14 years, plus a Python script.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recoll&lt;/li&gt;
&lt;li&gt;The Rule: Never Let a Book Into Context&lt;/li&gt;
&lt;li&gt;
The Four Steps It Takes

&lt;ul&gt;
&lt;li&gt;Level 1: Which books cover this&lt;/li&gt;
&lt;li&gt;Level 2: Where inside the book&lt;/li&gt;
&lt;li&gt;Level 3: Read the prose&lt;/li&gt;
&lt;li&gt;Level 4: Cite it&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Books for the Foundation, the Web for This Week&lt;/li&gt;
&lt;li&gt;The One Thing That Isn’t Standalone&lt;/li&gt;
&lt;li&gt;Where It Stands&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recoll
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.recoll.org" rel="noopener noreferrer"&gt;Recoll&lt;/a&gt; is a desktop full-text search tool. You point it at a folder, it indexes everything inside (PDF, EPUB, MOBI, DOC, whatever it has a filter for) into a Xapian database, and then you can query that database from the command line with &lt;code&gt;recollq&lt;/code&gt;. &lt;code&gt;recollq&lt;/code&gt; reads the index off disk. There is no running service.&lt;/p&gt;

&lt;p&gt;A coding agent is good at running shell commands and reading their output. It doesn’t need a semantic search layer to find the Stoicism books. A semantic layer would also surface chunks on adjacent topics you didn’t have words for, and this won’t. The trade is worth it: what comes back here is whole books, not the tiny chunks an embedding index deals in. It needs a query language that supports phrases and proximity, and here’s Recoll’s:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;term1 term2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;implicit AND&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"exact phrase"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;phrase match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;"two words"p3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;within 3 words of each other&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-term&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exclude&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ext:epub&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;filter by format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dir:"/path/folder"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;restrict to a folder&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The agent writes the query. What it can’t do is handle what comes back.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rule: Never Let a Book Into Context
&lt;/h2&gt;

&lt;p&gt;A large PDF extracts to 600KB of text, most of a 200K-token context window. Let an agent &lt;code&gt;cat&lt;/code&gt; that, or run &lt;code&gt;pdftotext&lt;/code&gt; on it with no output file, and one book just burned most of the session.&lt;/p&gt;

&lt;p&gt;So a core rule of the skill:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Never&lt;/strong&gt; &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;pdftotext&lt;/code&gt;, or &lt;code&gt;recollq -d&lt;/code&gt; a book straight into context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygogfibp11d9vnvregy5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fygogfibp11d9vnvregy5.jpg" alt="The Rule: Never Let a Book Into Context" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything goes through &lt;code&gt;scripts/shelf.py&lt;/code&gt;, a stdlib-only Python script (562 lines). Each subcommand caps what it prints. Full extractions go to &lt;code&gt;~/.cache/ebook-research/&lt;/code&gt; on disk, and the agent gets back a slice plus the path to the rest. If it needs more, it reads the cache file with an offset and a limit, or re-runs with &lt;code&gt;--grep&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four Steps It Takes
&lt;/h2&gt;

&lt;p&gt;The skill walks the agent down four levels and tells it never to stop at the first one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 1: Which books cover this
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 scripts/shelf.py search &lt;span class="s1"&gt;'"negative visualization"'&lt;/span&gt; --books 5 --snips 1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ranks books, not fragments, and handles duplicates. Here’s a real run against my library while I was writing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"negative visualization"&lt;/span&gt;
&lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="n"&gt;matched&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;showing&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;guide&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;life&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ancient&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;art&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Stoic&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;joy&lt;/span&gt;
    &lt;span class="n"&gt;epub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt;
    &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="n"&gt;Section0004&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xhtml&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="n"&gt;U&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="n"&gt;Negative&lt;/span&gt; &lt;span class="n"&gt;Visualization&lt;/span&gt; &lt;span class="n"&gt;What&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mf"&gt;101_Essays_Interior&lt;/span&gt;&lt;span class="mi"&gt;-107&lt;/span&gt;
    &lt;span class="n"&gt;epub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt; &lt;span class="mi"&gt;71&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt;
    &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="n"&gt;id34&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Practice&lt;/span&gt; &lt;span class="n"&gt;negative&lt;/span&gt; &lt;span class="n"&gt;visualization&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;tangible&lt;/span&gt; &lt;span class="n"&gt;solutions&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Stoicism&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Art&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Happiness&lt;/span&gt;
    &lt;span class="n"&gt;epub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt; &lt;span class="mi"&gt;71&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt;
    &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;duplicate&lt;/span&gt; &lt;span class="n"&gt;cop&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ies&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt; &lt;span class="n"&gt;elsewhere&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;library&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="n"&gt;id11&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;He&lt;/span&gt; &lt;span class="n"&gt;coined&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;negative&lt;/span&gt; &lt;span class="n"&gt;visualization&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;refer&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Stoic&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Become&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;Effective&lt;/span&gt; &lt;span class="n"&gt;Software&lt;/span&gt; &lt;span class="n"&gt;Engineering&lt;/span&gt; &lt;span class="n"&gt;Manager&lt;/span&gt;
    &lt;span class="n"&gt;epub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt; &lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt;
    &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="n"&gt;f_0083&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;regular&lt;/span&gt; &lt;span class="n"&gt;practicing&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;negative&lt;/span&gt; &lt;span class="n"&gt;visualization&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;we&lt;/span&gt; &lt;span class="n"&gt;imagine&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Handbook_for_New_Stoics_7P&lt;/span&gt;&lt;span class="mi"&gt;-65&lt;/span&gt;
    &lt;span class="n"&gt;epub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;hit&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt; &lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt;
    &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="n"&gt;MovingForward&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xhtml&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;engage&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;negative&lt;/span&gt; &lt;span class="n"&gt;visualization&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;practicing&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="n"&gt;denial&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fourteen hits and a whole chapter in William Irvine’s &lt;em&gt;A Guide to the Good Life&lt;/em&gt; versus one passing mention in a software engineering management book. That spread is the signal. (Of course a management book covers negative visualization. Imagining the worst is the job.)&lt;/p&gt;

&lt;p&gt;This is what happens without the quotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query: negative visualization
38 books matched (showing 5)

[1] BeautifulVisualization - Unknown
    pdf, 2 hit(s), rel 28%

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thirty-eight books, led by an O’Reilly data-viz book. Stemming is on by default, and an unquoted query is an AND, so anything with “negative” somewhere and “visualization” somewhere wins. The skill tells the agent to quote phrases for this reason. Level 1 snippets are 40 characters. They’re good for ranking books and worthless as evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 2: Where inside the book
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 scripts/shelf.py hits &lt;span class="s2"&gt;"/path/to/book.epub"&lt;/span&gt; &lt;span class="s1"&gt;'"negative visualization"'&lt;/span&gt; --max 12

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lists every matching section with a ready-to-paste locator: &lt;code&gt;--page N&lt;/code&gt; for a PDF, &lt;code&gt;--ipath "chapter.xhtml"&lt;/code&gt; for an EPUB. EPUBs have no page numbers, so the skill locates them by chapter file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 3: Read the prose
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 scripts/shelf.py &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="s2"&gt;"/path/A-guide-to-the-good-life.epub"&lt;/span&gt; \
    --ipath &lt;span class="s2"&gt;"Section0004.xhtml"&lt;/span&gt; --grep &lt;span class="s2"&gt;"negative visualization"&lt;/span&gt; --matches 1 --chars 800

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9y5fyxpxo1y90914vzkn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9y5fyxpxo1y90914vzkn.jpg" alt="Level 3: Read the actual prose" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What comes back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A-guide-to-the-good-life-the-ancient-art-of-Stoic-joy.epub — chapter Section0004.xhtml
5869 words, 33963 chars → full text saved to:
~/.cache/ebook-research/A-guide-to-the-good-life-...-Section0004-xhtml.txt
---
F O U R
Negative Visualization
What's the Worst That Can Happen?
...
Doing this, the Stoics thought, will make us value our wife, our car,
and our job more than we otherwise would. This technique — let us refer
to it as negative visualization — was employed by the Stoics at least as
far back as Chrysippus. It is, I think, the single most valuable
technique in the Stoics' psychological tool kit.
--- 1 passage(s) shown; read [cache file] for the rest

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A 34,000-character chapter, and 800 characters of it entered the context. The rest is on disk if the agent wants it.&lt;/p&gt;

&lt;p&gt;Nice of the chapter to ask. “What’s the worst that can happen?” is the whole question behind the Rule, and the answer is 600KB of PDF in the context window.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 4: Cite it
&lt;/h3&gt;

&lt;p&gt;Every claim the agent pulls from the library carries a title, an author, and a locator. When several books agree, it says so. When they disagree, it says that too.&lt;/p&gt;

&lt;p&gt;The skill also tells the agent to distinguish “this book asserts” from “this is established.” A book is one author’s argument, not a fact-check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Books for the Foundation, the Web for This Week
&lt;/h2&gt;

&lt;p&gt;The skill says it’s the wrong tool for anything current. Model releases, framework versions, news: web search. Books are for what’s settled, deep, or conceptual. Philosophy, craft, history, psychology, business principles, the theory underneath a thing.&lt;/p&gt;

&lt;p&gt;Many questions want both. The skill does a &lt;a href="https://dev.to/eristoddle/eleven-deep-research-tools-that-live-inside-your-coding-agent-and-the-one-i-forked-4l7p"&gt;web pass&lt;/a&gt; for what changed this month, then a library pass for the principle under it, presented separately. A claim from a 2015 book never blends into a paragraph about this week’s news.&lt;/p&gt;

&lt;p&gt;And if the library has nothing good, the agent says so and goes back to the web. Even a library this size has holes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa8obazq32i5zqjknciir.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa8obazq32i5zqjknciir.jpg" alt="Porting It: What" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The One Thing That Isn’t Standalone
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.recoll.org/pages/download.html" rel="noopener noreferrer"&gt;Install Recoll&lt;/a&gt;, point its indexing config at your ebook folder (the indexing preferences in the GUI on first launch, or a &lt;code&gt;topdirs&lt;/code&gt; line in &lt;code&gt;~/.recoll/recoll.conf&lt;/code&gt;), run &lt;code&gt;recollindex&lt;/code&gt;, and wait. Mine took about 15 minutes.&lt;/p&gt;

&lt;p&gt;There’s no live monitor, so after you add books re-run &lt;code&gt;recollindex&lt;/code&gt;. The skill tells the agent to suggest you run it yourself in case your forget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It Stands
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/eristoddle/agent-skills/tree/main/skills/ebook-research" rel="noopener noreferrer"&gt;&lt;code&gt;skills/ebook-research&lt;/code&gt;&lt;/a&gt; in the agent-skills repo, a &lt;code&gt;SKILL.md&lt;/code&gt; and one Python script, next to &lt;code&gt;fetch-anything&lt;/code&gt; and &lt;a href="https://dev.to/eristoddle/two-files-and-a-skill-how-i-plan-ai-coding-projects-without-a-framework-55nl"&gt;living-plan&lt;/a&gt;. If you use &lt;a href="https://dev.to/eristoddle/the-agent-skills-guide-i-wish-id-had-17i1"&gt;agent skills&lt;/a&gt;, you know where the folder goes. If you have a folder full of PDFs and EPUBs you bought and never finished, you already have a better research corpus than whatever your agent gets from a search engine.&lt;/p&gt;

</description>
      <category>recoll</category>
      <category>codingagent</category>
      <category>agentskills</category>
      <category>ebookresearch</category>
    </item>
    <item>
      <title>Claude Fable 5.2 Hands Its Riskiest Questions to Opus 4.8</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 10 Nov 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/claude-fable-52-hands-its-riskiest-questions-to-opus-48-g3b</link>
      <guid>https://dev.to/eristoddle/claude-fable-52-hands-its-riskiest-questions-to-opus-48-g3b</guid>
      <description>&lt;p&gt;Anthropic shipped Claude Fable 5.2 on November 9, and within a day it was the top model on Artificial Analysis with a 65, the highest score on that index so far. It’s also cheaper than the model it replaces: $8 in and $40 out per million tokens, down from $10/$50 for Fable 5.1. On paper that’s the easiest upgrade of the year.&lt;/p&gt;

&lt;p&gt;Then you read the label next to the score. Every Fable 5.2 entry on AA says “Default Fallback.” When Anthropic’s classifiers decide a request looks like offensive security work or risky biology, Fable 5.2 doesn’t answer it. An older model does. So the new number one is partly a routing decision, and nobody has said how much of the 65 came from the router.&lt;/p&gt;

&lt;p&gt;Meanwhile, the cheap end of the market got crowded. Meta and Tencent both launched this week, and my cheapskate table barely noticed. Two of its lines changed, and both moves started at the top: Gemini 4 Argon retook Creative Writing and Instruction Following, which reset those cutoffs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Claude Fable 5.2: read the label

&lt;ul&gt;
&lt;li&gt;What it costs to run&lt;/li&gt;
&lt;li&gt;The fallback&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The cheap end got crowded: Muse Ember and Hy4

&lt;ul&gt;
&lt;li&gt;Muse Ember&lt;/li&gt;
&lt;li&gt;Tencent Hy4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Kimi K3.1 Pro gets rated and ships its weights&lt;/li&gt;
&lt;li&gt;The rest of the board&lt;/li&gt;
&lt;li&gt;
The cheapskate table

&lt;ul&gt;
&lt;li&gt;What held&lt;/li&gt;
&lt;li&gt;What moved, and why&lt;/li&gt;
&lt;li&gt;Minus the model you can’t call&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Local sweet spot&lt;/li&gt;
&lt;li&gt;
Horror stories

&lt;ul&gt;
&lt;li&gt;Claude Code put your email in its requests&lt;/li&gt;
&lt;li&gt;Kimi K3.1 Pro answered with encrypted-looking noise&lt;/li&gt;
&lt;li&gt;Goldman cut the bankers off&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What’s coming&lt;/li&gt;
&lt;li&gt;Finally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Claude Fable 5.2: read the label
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.anthropic.com/claude-fable-and-mythos-5-2" rel="noopener noreferrer"&gt;Anthropic’s announcement&lt;/a&gt; bundles two releases. Mythos 5.2 is the unrestricted version, available only through Anthropic’s cyber and life-science verification programs. Fable 5.2 is the same underlying model with safeguards bolted on, and it’s what you can actually buy. Anthropic claims better coding, reasoning, and vision, and output up to 30 percent faster. There’s also a fast mode at $16/$80 for people who want it sooner and don’t mind paying double.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fortune.com/2026/11/09/anthropic-debuts-updated-claude-fable-and-mythos-models-undercutting-price-of-openais-gpt-6-astra-by-up-to-80/" rel="noopener noreferrer"&gt;Fortune&lt;/a&gt; framed the price as a shot at OpenAI, and it is: GPT-6 Astra lists at $10/$50, so Fable 5.2 is 20 percent cheaper per token. The per-task numbers point the other way at the top of the effort dial.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it costs to run
&lt;/h3&gt;

&lt;p&gt;Here’s how the top of &lt;a href="https://artificialanalysis.ai/leaderboards/models" rel="noopener noreferrer"&gt;AA’s leaderboard&lt;/a&gt; looks now, with Fable 5.2 at every effort level:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model and effort&lt;/th&gt;
&lt;th&gt;AA Index&lt;/th&gt;
&lt;th&gt;Cost per AA task&lt;/th&gt;
&lt;th&gt;Minutes per task&lt;/th&gt;
&lt;th&gt;First answer token&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.2, max&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;$26.54&lt;/td&gt;
&lt;td&gt;44.6&lt;/td&gt;
&lt;td&gt;221.21s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.2, xhigh&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;$14.83&lt;/td&gt;
&lt;td&gt;26.3&lt;/td&gt;
&lt;td&gt;74.59s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.2, high&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;$9.08&lt;/td&gt;
&lt;td&gt;17.4&lt;/td&gt;
&lt;td&gt;30.52s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 4 Carbon, high&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;td&gt;$7.76&lt;/td&gt;
&lt;td&gt;26.0&lt;/td&gt;
&lt;td&gt;67.98s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5.5, max&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;$10.04&lt;/td&gt;
&lt;td&gt;25.1&lt;/td&gt;
&lt;td&gt;372.14s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6 Astra, max&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;$6.24&lt;/td&gt;
&lt;td&gt;23.6&lt;/td&gt;
&lt;td&gt;227.18s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.2, medium&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;$3.80&lt;/td&gt;
&lt;td&gt;8.3&lt;/td&gt;
&lt;td&gt;12.60s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol, max&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;$1.27&lt;/td&gt;
&lt;td&gt;20.0&lt;/td&gt;
&lt;td&gt;142.12s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Fable 5.2, low&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;$3.10&lt;/td&gt;
&lt;td&gt;6.5&lt;/td&gt;
&lt;td&gt;6.38s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Max effort buys three points over high and costs almost three times as much. Fable 5.2 at max runs $26.54 a task, more than four times Astra at max. High is the setting that makes sense: 62 for $9.08, which beats Opus 5.5 at max on both score and price and finishes in about two-thirds the time. And GPT-6.1 Sol at max is still sitting there at 55 for $1.27, if you need “very good” rather than “best.”&lt;/p&gt;

&lt;p&gt;AA renamed its latency column to “first answer token” this week, so don’t line these up against the time-to-first-token numbers I printed last week.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fallback
&lt;/h3&gt;

&lt;p&gt;Here’s how it works, per &lt;a href="https://www.notebookcheck.net/Claude-Fable-5-2-fallbacks-make-AI-agents-more-vulnerable.1446771.0.html" rel="noopener noreferrer"&gt;Notebookcheck&lt;/a&gt; and the system card. Classifiers check every request for offensive cybersecurity, dangerous biology, and some kinds of AI development work. If one fires, the request goes to Opus 4.8 (cyber) or Opus 5 (biology) instead. On the API you have to opt into that fallback. If you don’t, the flagged request just gets refused.&lt;/p&gt;

&lt;p&gt;Anthropic says Fable 5.2 blocks about 55 percent less often than 5.1, and about 60 percent less on cyber. Its prompt-injection numbers deserve a second look. Fable 5.2 had a 28.16 percent attack success rate, with fallback triggering 99.5 percent of the time. Opus 5.5 came in at 11.13 percent, with 64 percent fallback. One reading is that the attacks mostly landed on whatever older model the router handed them to, not on Fable itself. Either way, if your agent touches untrusted input, what you’re actually deploying is a router in front of Fable 5.2 and two older Opus models.&lt;/p&gt;

&lt;p&gt;AA labels its scores “Default Fallback,” so they measure that whole system too. I couldn’t find anything saying how many of AA’s tasks got rerouted, or what the score would be without the router. And one more line from &lt;a href="https://techcrunch.com/2026/11/09/anthropic-releases-new-mythos-and-fable-models-amid-rsi-concerns/" rel="noopener noreferrer"&gt;TechCrunch&lt;/a&gt;: Anthropic says these models suspect they’re being evaluated more often than its recent ones do.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://news.ycombinator.com/item?id=50429068" rel="noopener noreferrer"&gt;Hacker News launch thread&lt;/a&gt; hit 691 points and 856 comments, and the thread about the AA score got another 355 points. OpenRouter logged 18.5 billion Fable 5.2 tokens on launch day. Arena hasn’t rated it yet, so it isn’t in my table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheap end got crowded: Muse Ember and Hy4
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Muse Ember
&lt;/h3&gt;

&lt;p&gt;Meta released Muse Ember the same day as Fable 5.2, and it’s the more interesting launch if you pay the bills. It’s $0.10 in and $0.50 out, with a 1M context window. It’s built for the boring work agents do all day: tool calls, routing, extraction. &lt;a href="https://techcrunch.com/2026/11/09/meta-releases-muse-ember-a-new-lightweight-model-for-agent-execution/" rel="noopener noreferrer"&gt;TechCrunch&lt;/a&gt; has the launch details. The weights aren’t public, and right now Meta is the only one serving it.&lt;/p&gt;

&lt;p&gt;At max effort it scores 36 on AA, same as Claude Haiku 5.5 at max. Haiku is the obvious thing to compare it to, so here’s that comparison with a few other cheap options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model and effort&lt;/th&gt;
&lt;th&gt;AA Index&lt;/th&gt;
&lt;th&gt;Cost per AA task&lt;/th&gt;
&lt;th&gt;Minutes per task&lt;/th&gt;
&lt;th&gt;$ in / $ out&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra, medium&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;$0.17&lt;/td&gt;
&lt;td&gt;2.6&lt;/td&gt;
&lt;td&gt;$1 / $5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Muse Ember, max&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;$0.14&lt;/td&gt;
&lt;td&gt;3.2&lt;/td&gt;
&lt;td&gt;$0.10 / $0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Haiku 5.5, max&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;$0.41&lt;/td&gt;
&lt;td&gt;14.8&lt;/td&gt;
&lt;td&gt;$0.10 / $0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol, low&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;$0.16&lt;/td&gt;
&lt;td&gt;1.7&lt;/td&gt;
&lt;td&gt;$2 / $10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MiMo-V2.6-Pro&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;$0.26&lt;/td&gt;
&lt;td&gt;36.8&lt;/td&gt;
&lt;td&gt;$0.435 / $0.87&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GLM-5.3-Flash&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;$0.58&lt;/td&gt;
&lt;td&gt;45.6&lt;/td&gt;
&lt;td&gt;$0.15 / $0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6 Luna, max&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;$0.15&lt;/td&gt;
&lt;td&gt;12.1&lt;/td&gt;
&lt;td&gt;$0.10 / $0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same score as Haiku at a third of the cost per task, and it finishes in under a quarter of the time. The sticker prices are identical. Ember just uses a lot fewer tokens to get there.&lt;/p&gt;

&lt;p&gt;Weigh two things before you switch. On FrontierCode 2.0-AA it scores 27.2 percent to Haiku’s 34.9 (&lt;a href="https://thenextweb.com/news/meta-muse-ember-small-ai-model-haiku-luna" rel="noopener noreferrer"&gt;The Next Web&lt;/a&gt;), so for coding subtasks Haiku is still ahead. And look at the top row: GPT-6.1 Terra at medium effort scores two points higher for three cents more a task, and it’s been on OpenRouter since October 26. Ember is just the newest of the cheap options.&lt;/p&gt;

&lt;p&gt;None of these have Arena ratings that put them in a band, and Ember has no Arena rating at all yet. Remember Haiku 5.5. It looked great on AA, then debuted on Arena at 126th Overall.&lt;/p&gt;

&lt;p&gt;There’s also a stealth model to watch. Crouton Alpha showed up on OpenRouter on November 3, free, with a million-token window and a description that sounds a lot like Ember’s: agent subtasks, tool use, pair it with a bigger model for planning. It did 5.1 trillion tokens this week, eighth on the board. People online think it’s Meta. Nobody has confirmed that, and it was still running after Ember launched. &lt;a href="https://openrouter.ai/stealth" rel="noopener noreferrer"&gt;OpenRouter’s stealth page&lt;/a&gt; warns that the provider may retain your prompts, so don’t send it anything sensitive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tencent Hy4
&lt;/h3&gt;

&lt;p&gt;Tencent released the full Hy4 on November 4. It’s the first Hy model with vision and computer use, with the same 1M window (&lt;a href="https://siliconangle.com/2026/11/04/tencent-releases-hy4-powerful-frontier-llm-introducing-visual-understanding-and-computer-use/" rel="noopener noreferrer"&gt;SiliconANGLE&lt;/a&gt;). It came in third on OpenRouter for the week at 16 trillion tokens, with only Tencent serving it, at $0.417/$1.25. Tencent’s request count on OpenRouter rose 21 percent.&lt;/p&gt;

&lt;p&gt;AA gives it a 35 at $1.03 a task. That’s the same score as Ember for about seven times the cost per task. Tencent itself admits Hy4 still trails the best commercial models “by a wide margin” on hard math and complex image analysis.&lt;/p&gt;

&lt;p&gt;Tencent is calling it open source, but the weights aren’t out. Tencent says they and the system card will land “in the coming days,” and &lt;a href="https://www.digitalapplied.com/blog/tencent-hy4-release-what-is-confirmed" rel="noopener noreferrer"&gt;Digital Applied&lt;/a&gt; reports the expected Hugging Face page was still returning a 401 on November 5. One commenter in the &lt;a href="https://news.ycombinator.com/item?id=50362313" rel="noopener noreferrer"&gt;HN thread&lt;/a&gt; summed it up in three words: “NOT open source.” The August preview weights were Apache 2.0, so the promise is believable. A cheaper Hy4 Flash is also “coming soon.”&lt;/p&gt;

&lt;p&gt;Sixteen trillion tokens in week one, from a single provider, with no Arena rating, looks to me like curiosity plus integrations. Hy4 is already wired into OpenCode and Hermes. It might turn out to be good, but week-one volume can’t tell you that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kimi K3.1 Pro gets rated and ships its weights
&lt;/h2&gt;

&lt;p&gt;Moonshot said the Kimi K3.1 Pro weights would be out by November 4, and they &lt;a href="https://huggingface.co/moonshotai/Kimi-K3.1-Pro" rel="noopener noreferrer"&gt;landed on Hugging Face&lt;/a&gt; right on time. It’s 2.8 trillion parameters with 104 billion active, about 1.56 TB of safetensors, under a custom modified-MIT license. You won’t be running it on your laptop.&lt;/p&gt;

&lt;p&gt;Arena finally rated it, too. It debuted 24th Overall at 1483.02 on 3,443 votes, 28th in Coding, 18th in Instruction Following, and 32nd in Hard Prompts. That puts it inside four of my six bands, and it isn’t the cheapest model in any of them at $10 output. On AA it scores 46 at $3.68 a task, with a 159.63-second wait for the first answer.&lt;/p&gt;

&lt;p&gt;OpenRouter traffic rose 56 percent, to 4.39 trillion tokens. The weirdest Kimi story of the week is in the horror section.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the board
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://openrouter.ai/rankings" rel="noopener noreferrer"&gt;OpenRouter’s&lt;/a&gt; week through November 9 goes to DeepSeek V4.1 Flash 1017 for the fourth week in a row: 55.4 trillion tokens, up 10 percent. The original V4.1 Flash is second at 17.5 trillion, also up. DeepSeek now has 31.8 percent of all text requests on the platform, and Arena still hasn’t rated the 1017 snapshot.&lt;/p&gt;

&lt;p&gt;GLM-5.3-Flash is fourth at 12.1 trillion, down 21 percent, and Z.ai’s request share fell 38 percent. GPT-6 Luna dropped 23 percent. Some of that traffic probably went to Hy4 and the free Crouton Alpha, but the chart doesn’t say where it went.&lt;/p&gt;

&lt;p&gt;On the apps list, Hermes Agent leads at 1.95 trillion tokens, then Claude Code at 1.38 trillion and Kilo Code at 851 billion.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheapskate table
&lt;/h2&gt;

&lt;p&gt;For anyone new: each Arena category gets a cutoff at the leader’s rating minus 50. The pick is the cheapest model, by output price, that clears that cutoff. A script filters all ~420 rows per category in &lt;a href="https://huggingface.co/datasets/lmarena-ai/leaderboard-dataset" rel="noopener noreferrer"&gt;LMArena’s leaderboard dataset&lt;/a&gt; (this week’s board is dated November 9) and records the first model under the cutoff, which proves the list wasn’t truncated. Every price is the model maker’s own endpoint on OpenRouter, with Carbon and Argon at the $10 intro rate.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;Gemini 4 Carbon (High) (1526)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Pro (1480, #30)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;−46&lt;/td&gt;
&lt;td&gt;11.5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;Gemini 4 Carbon (High) (1567)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1527, #27)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−41&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;Gemini 4 Argon (High) (1525)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;Gemini 3.8 Flash (High) (1489, #9)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−36&lt;/td&gt;
&lt;td&gt;2.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;Gemini 4 Argon (High) (1529)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;Gemini 3.8 Flash (High) (1492, #13)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−37&lt;/td&gt;
&lt;td&gt;2.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;Gemini 4 Carbon (High) (1546)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1500, #35)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−47&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;Gemini 4 Argon (High) (1531)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1504, #11)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−27&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Band depths: Overall 33, Coding 43, Creative 14, Instruction Following 24, Hard Prompts 41, Math 37. Carbon’s Coding rating slipped 6.2 points, which is why the Coding band went from 29 models to 43.&lt;/p&gt;

&lt;h3&gt;
  
  
  What held
&lt;/h3&gt;

&lt;p&gt;Four of six lines didn’t move. MiMo-V2.6-Pro keeps Overall at 87 cents, 4.09 points over the line. GLM-5.3-Flash keeps Coding, Hard Prompts, and Math at 50 cents. Its Hard Prompts rating stands on 32,023 votes, the most of any pick on the table. It missed the Overall band by 1.74 points.&lt;/p&gt;

&lt;p&gt;The trade with both of these is speed. AA puts GLM-5.3-Flash at 45.6 minutes per task and MiMo-V2.6-Pro at 36.8. If you’re running a tight agent loop, that’s where the savings go.&lt;/p&gt;

&lt;h3&gt;
  
  
  What moved, and why
&lt;/h3&gt;

&lt;p&gt;Creative Writing and Instruction Following changed because of the top of the board. Argon took Creative Writing back from Claude Opus 5.5 (1524.61 to 1517.83). Last week’s ratio was 5.3× because the leader cost $20. This week the leader costs $10, so the ratio fell to 2.7×.&lt;/p&gt;

&lt;p&gt;Argon now leads Instruction Following too, with Carbon second. Last week’s IF pick, DeepSeek V4.1 Flash (the September 10 snapshot), dropped to 1475.64 and missed this week’s cutoff by 3.15. GLM-5.3-Flash missed by 4.48. So Gemini 3.8 Flash takes both Creative and IF at $3.75. It ties Gemini 3.7 Flash on price and has the higher rating.&lt;/p&gt;

&lt;p&gt;One caveat on Gemini 3.8 Flash. AA puts it at $7.77 per task at high effort, which is one cent more than Carbon at high. It burns a lot of reasoning tokens. AA’s tasks are hard agentic evals, not short stories, so this says little about prose, but for agent work the $3.75 sticker is a long way from the bill.&lt;/p&gt;

&lt;p&gt;Those two categories are where you’re mostly paying for quality. Their bands bottom out at $3.75.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minus the model you can’t call
&lt;/h3&gt;

&lt;p&gt;Carbon still leads three categories, and it’s still only open to cyber defenders in Google’s Fairwind program. Here’s the same method with Carbon taken out:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader (ex-Carbon)&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;Gemini 4 Argon (High) (1522)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1474, #39)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−48&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;Gemini 4 Argon (High) (1553)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Flash (1512, #54)&lt;/td&gt;
&lt;td&gt;$0.28&lt;/td&gt;
&lt;td&gt;−41&lt;/td&gt;
&lt;td&gt;35.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;Gemini 4 Argon (High) (1546)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1500, #34)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−46&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Argon already leads Creative, IF, and Math, so those rows stay put. Without Carbon, the Overall band is 45 deep and Coding is 73. GLM-5.3-Flash clears the Argon-based Overall cutoff by 1.83. MiMo-V2.6-Flash clears Coding by 8.79, and it’s the slowest thing on this page: 64.8 minutes per AA task.&lt;/p&gt;

&lt;p&gt;On December 1, Argon goes to $4/$20, and every Argon-led ratio in both tables doubles without a single pick moving.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local sweet spot
&lt;/h2&gt;

&lt;p&gt;For each machine I take the highest-rated model whose file leaves memory free for context and that measures at least 15 tokens a second.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your machine&lt;/th&gt;
&lt;th&gt;Pick&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Arena&lt;/th&gt;
&lt;th&gt;AA&lt;/th&gt;
&lt;th&gt;Measured tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mac 16GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;27 (n=4, 6-82)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 32GB&lt;/td&gt;
&lt;td&gt;qwen3.8-27b MLX 4bit&lt;/td&gt;
&lt;td&gt;16.1 GB&lt;/td&gt;
&lt;td&gt;1433 (#112)&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 64GB+&lt;/td&gt;
&lt;td&gt;gemma-4-31b Q4_K_M&lt;/td&gt;
&lt;td&gt;18.3 GB&lt;/td&gt;
&lt;td&gt;1452 (#78)&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 12GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;50 (n=1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 24GB&lt;/td&gt;
&lt;td&gt;gemma-4-31b Q4_K_M&lt;/td&gt;
&lt;td&gt;18.3 GB&lt;/td&gt;
&lt;td&gt;1452 (#78)&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same picks as last week. This week’s big open-weight drop, Kimi K3.1 Pro at 1.56 TB, is about 85 times the size of the Gemma file. Nothing at 9B has an Arena rating, so those two rows are simply the largest model that fits. The AA numbers here are from the old v4.3.2 index, not v5.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horror stories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Claude Code put your email in its requests
&lt;/h3&gt;

&lt;p&gt;The most-upvoted horror story of the week was about Anthropic’s own coding tool. A &lt;a href="https://news.ycombinator.com/item?id=50385272" rel="noopener noreferrer"&gt;Hacker News thread&lt;/a&gt; titled “Claude Code sends your email address to websites” reached 1,612 points. Users found their account email showing up in the User-Agent header when Claude Code fetched web pages. One person reported “dozens of scam and phishing emails per day from properties I have never personally visited.” Another said the spam arriving in their work inbox was personalized with their first and last name.&lt;/p&gt;

&lt;p&gt;One commenter’s theory: some APIs, like the SEC’s EDGAR, ask for a contact email in the User-Agent, and the model had one sitting right there in its context, so it used it. That’s still a theory. Anthropic did confirm a fix. Lydia Hallie, who works on Claude Code, posted: “We’re removing the account email address from the context Claude Code gives the model,” with the change due in the next release.&lt;/p&gt;

&lt;p&gt;If oddly personal spam started around the time you installed Claude Code, this might be why. Anything in your agent’s context can end up in a request to a server you’ve never heard of.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kimi K3.1 Pro answered with encrypted-looking noise
&lt;/h3&gt;

&lt;p&gt;Peter Nutter gave Kimi K3.1 Pro a &lt;code&gt;send_message&lt;/code&gt; tool in a Codex-style multi-agent setup. A worker agent was supposed to solve a small problem and report the result to another agent. In 25 of 160 episodes, 15.6 percent, it sent a &lt;a href="https://www.peterstran.com/projects/kimi-fernet/" rel="noopener noreferrer"&gt;blob that looked like Fernet ciphertext&lt;/a&gt; instead. “The header is right and the body is noise,” he writes. Retries mostly produced more blobs, and a rerun a day later did it 16 times out of 79. None of the blobs matched any of about 184,000 public Fernet strings he checked against.&lt;/p&gt;

&lt;p&gt;Nutter notes that the timestamps inside the blobs cluster in late July 2026 and says, “We can’t prove any of this was intentional.” Whatever the cause, it’s a failure that’s easy to miss: a multi-agent pipeline where one worker drops its report one time in seven, and the log shows a message that looks fine at a glance. Put a check on what your workers send back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Goldman cut the bankers off
&lt;/h3&gt;

&lt;p&gt;A smaller one. Goldman Sachs limited Claude Code and GitHub’s coding tools to its roughly 12,000 engineers, out of about 47,000 staff, and traders and bankers lost access (&lt;a href="https://www.fstech.co.uk/fst/Goldman_Sachs_Restricts_AI_Coding_Tools_For_Traders_And_Bankers.php" rel="noopener noreferrer"&gt;FStech&lt;/a&gt;, citing Bloomberg). Goldman says it reviewed productivity and risk. In the HN discussion, someone at another company said theirs is “clawing back Claude access because of chronic billing overages.” It’s one comment. Anyone who has looked at Fable’s $26.54-per-task max setting will understand the instinct.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming
&lt;/h2&gt;

&lt;p&gt;Tencent says the Hy4 weights and system card are “coming days” away, and Hy4 Flash is “soon.” Argon goes to $4/$20 on December 1. Google still hasn’t set a date for Carbon’s wider rollout.&lt;/p&gt;

&lt;p&gt;The rumor list is long and all of it comes from one &lt;a href="https://x.com/mark_k/status/2117323044213625181" rel="noopener noreferrer"&gt;post on X&lt;/a&gt;: GPT-6.2 Astra between November 2 and 15, GPT-6.2 Sol between November 10 and 15, DeepSeek V4.1 Pro around November 12, Qwen 4 Max around November 16, and Grok 4.8 sometime between November 19 and 30. None of it is confirmed, and more than half of the GPT-6.2 Astra window is already gone with nothing shipped.&lt;/p&gt;

&lt;p&gt;On Arena, I’m waiting for Fable 5.2, Hy4, Muse Ember, DeepSeek 1017, GPT-6.1 Terra, and MiniMax M3.1 Flash. Polymarket gives Hy4 a 78 percent chance of debuting at 1480 or better, which would put it on the edge of the Overall band.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;If you want the best model and price isn’t the issue, Fable 5.2 at high effort is the pick this week: 62 on AA for $9.08 a task. Just know that anything security-flavored may get answered by Opus 4.8, and turn on the API fallback on purpose so you aren’t surprised by refusals. If you’re paying the bills, the Carbon-free table still says GLM-5.3-Flash at 50 cents for most things and MiMo-V2.6-Flash at 28 cents for coding, as long as you can wait for them. And if you run a lot of small agent steps, Muse Ember and GPT-6.1 Terra at medium are both worth a test against whatever you’re using now.&lt;/p&gt;

&lt;p&gt;Next week should bring Fable 5.2’s first Arena rating and either Hy4’s weights or another week of “coming days.” I’ll also be checking whether GPT-6.2 shows up before its rumored window closes.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
      <category>modelroundup</category>
      <category>largelanguagemodels</category>
    </item>
    <item>
      <title>Stop Asking AI to Fix the Whole Problem: The Zwicky Box Method</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 05 Nov 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/stop-asking-ai-to-fix-the-whole-problem-the-zwicky-box-method-1lhk</link>
      <guid>https://dev.to/eristoddle/stop-asking-ai-to-fix-the-whole-problem-the-zwicky-box-method-1lhk</guid>
      <description>&lt;p&gt;I have a Python script called &lt;code&gt;ai_report.py&lt;/code&gt; that builds me an AI news report every day. It pulls about twenty RSS feeds (Anthropic, OpenAI, Simon Willison, Latent.Space, a pile of Medium tags), a dozen subreddits, and a few Hacker News searches. It scores everything, dedupes it against a persistent index, sorts it into categories, writes one markdown file, and emails it to me every morning. Nobody reads it but me.&lt;/p&gt;

&lt;p&gt;And I mostly don’t read it either. It returns so much that opening it feels like a chore, and the only filter that actually works is me, skimming, on the days I bother.&lt;/p&gt;

&lt;p&gt;I have thought about fixing it a few times, but just &lt;a href="https://dev.to/eristoddle/my-ai-agent-kept-making-shit-up-and-other-lessons-from-running-openclaw-566p"&gt;getting it to work in the first place was a pain in the ass&lt;/a&gt;. But that was probably the same month that OpenClaw came out and switched names three or four times. So models were dumber then.&lt;/p&gt;

&lt;p&gt;All the scoring, deduping, and other stuff I had it do was simply because the list was too damn long. So this time I asked a model the question the way I’d been asking it in my head. Claude Sonnet 5, through OpenRouter, a paragraph describing the script, and then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do I fix it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer was good. It told me I’d built “a collection pipeline, not a filtering pipeline,” then told me to rank everything, take a hard top N (“5, maybe 8”), and use an LLM as the judge against a written description of my taste. Tier the list. Archive the rest. Tune the prompt weekly.&lt;/p&gt;

&lt;p&gt;I’d probably have built that. And I’d have ended up with a shorter file I don’t read.&lt;/p&gt;

&lt;p&gt;This post is taking that problem and using a specific creativity method on it: take the thing apart before you try to solve it. It has four steps, each one a different tool for breaking things down. I also hand the tedious part to a model and keep the part it can’t do for myself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step One: Ask Why Until the Problem Changes Shape&lt;/li&gt;
&lt;li&gt;Step Two: List What the Thing Is Made Of&lt;/li&gt;
&lt;li&gt;Step Three: Change All of Them at Once&lt;/li&gt;
&lt;li&gt;
Step Four: Hand the Model the Tedious Part

&lt;ul&gt;
&lt;li&gt;What came back&lt;/li&gt;
&lt;li&gt;Where it went wrong&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Part You Can’t Hand Over&lt;/li&gt;
&lt;li&gt;The Cell I Circled&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step One: Ask Why Until the Problem Changes Shape
&lt;/h2&gt;

&lt;p&gt;The first tool came out of a loom factory. Sakichi Toyoda, whose company became Toyota, is usually credited with the habit of asking “why” five times when something breaks, and Taiichi Ohno made it famous as part of the Toyota Production System. The first answer to “why” is almost always just the symptom.&lt;/p&gt;

&lt;p&gt;First, on paper, with no AI model:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frhdyziujpn47lb9pld6y.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frhdyziujpn47lb9pld6y.jpg" alt="Step One: Ask Why Until the Problem Changes Shape" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Why don’t I read the report?&lt;/strong&gt; Because it’s too long.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why is it too long?&lt;/strong&gt; Because it returns everything that survives dedup, and dedup only removes repeating items. It does nothing with what I don’t care about.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why doesn’t anything remove what I don’t care about?&lt;/strong&gt; Because the scoring only sorts. It ranks each item by how much it looks like articles I’ve clipped, and then keeps all of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why would a longer list be a problem at all?&lt;/strong&gt; I could just skim. More items means I read fewer of them, not more. Digests are normally tuned on the assumption that more is better, and for a reader of one, that assumption runs backwards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why is it built as a daily digest?&lt;/strong&gt; Because that’s what news reports look like. I never decided it. It was the default.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Look at where that landed. I started with “it’s too long” and ended with “I inherited a format I never chose, and the format sucks.” The model’s answer to the whole question was a fix for answer number one. A shorter daily digest is still a daily digest.&lt;/p&gt;

&lt;p&gt;And five is not a magic number. You stop when the answer stops being about the symptom. Sometimes that’s three whys and sometimes it’s eight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two: List What the Thing Is Made Of
&lt;/h2&gt;

&lt;p&gt;Now that I know the format is the problem, I need to see the format in parts.&lt;/p&gt;

&lt;p&gt;Robert P. Crawford laid out the tool for this in his 1954 book &lt;em&gt;The Techniques of Creative Thinking&lt;/em&gt;, and it’s called attribute listing. You write down every attribute of the thing you’re trying to improve, the literal ones, and then you change them one at a time and see what each change gives you.&lt;/p&gt;

&lt;p&gt;Here’s my report, listed out:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;What it is now&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The unit&lt;/td&gt;
&lt;td&gt;One item per article, after dedup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who filters&lt;/td&gt;
&lt;td&gt;A sort that cuts nothing, then me&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume&lt;/td&gt;
&lt;td&gt;No real cap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cadence&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;A markdown file, emailed to me&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Crawford’s move is to change one at a time. So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Change the volume:&lt;/strong&gt; cap it at the top 8. That’s the model’s answer, almost word for word.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change the cadence:&lt;/strong&gt; make it weekly. Fewer files, same problem, just once a week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Change the output:&lt;/strong&gt; skip the email and drop it straight into my vault. Now it’s a long note I don’t read.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every single-attribute change is a fix I’ve already thought of. Changing one thing at a time is how you improve a design you’re happy with. I’m not happy with this one. I need to change several attributes at once, and use a different tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three: Change All of Them at Once
&lt;/h2&gt;

&lt;p&gt;Fritz Zwicky was a Swiss astronomer at Caltech, the one who proposed dark matter in 1933 and spent the rest of his career being right a decade before everyone else. During the 1940s he did engineering work on jet and rocket propulsion at Aerojet, and that’s where he built the tool he spent his later years evangelizing. He called it the morphological approach. Most people now call the grid itself a Zwicky box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn2miue5miaa18p5qwhnb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn2miue5miaa18p5qwhnb.jpg" alt="Step Three: Change All of Them at Once" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is simple, but the work is not:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Break the problem into &lt;strong&gt;independent parameters.&lt;/strong&gt; If changing one forces a change in another, they’re the same parameter with two names.&lt;/li&gt;
&lt;li&gt;For each parameter, list &lt;strong&gt;every value you can think of.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Walk all the combinations.&lt;/strong&gt; The interesting answer is usually a combination nobody would have proposed as a whole.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My attribute list from step two is already most of the way to step one, which is why I did Crawford first. Turning attributes into parameters is mostly a matter of asking “what else could this be?” for each row:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Values&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(a) single item · (b) a cluster of items about the same story · (c) one item per source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Who filters&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(a) keyword rules · (b) a model scoring each item · (c) similarity to articles I’ve clipped into my notes by hand · (d) nobody, I filter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Volume rule&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(a) fixed top N · (b) score threshold · (c) no cap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cadence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(a) daily · (b) weekly · (c) only when something crosses a bar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(a) a markdown file · (b) an email · (c) it feeds my weekly blog posts directly, not me&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That (c) under “Who filters” is not random. I &lt;a href="https://dev.to/eristoddle/obsidians-new-web-clipper-youll-want-to-try-it-4ifp"&gt;clip articles into my Obsidian vault&lt;/a&gt; by hand, deliberately. Those clips are a record of what I found worth keeping, and the report already uses them, but only to decide what order to show me everything in.&lt;/p&gt;

&lt;p&gt;The (c) under “Output” is the far end of that row: the version where the report stops being for me at all. I’d never pick it, but a Zwicky box is supposed to have values you’d never pick. That’s how you find out where the edges are.&lt;/p&gt;

&lt;p&gt;3 X 4 X 3 X 3 X 3 is 324 combinations.&lt;/p&gt;

&lt;p&gt;Now put the model’s first answer on this grid. It’s one cell: single item, model scoring, top N, daily, email. My current report is single item, nobody filters (the sort cuts nothing), no cap, daily, email. The answer to “how do I fix it?” changed two of the five values. It’s the cell next door.&lt;/p&gt;

&lt;p&gt;That’s not a bad answer. It’s &lt;a href="https://dev.to/eristoddle/youre-using-ai-like-a-vending-machine-3gf2"&gt;the &lt;em&gt;average&lt;/em&gt; answer&lt;/a&gt;, the one that’s the closest to what I already have. Sure, a better question would get a better answer, but nobody opens with a Zwicky box. The default question buys the cell next door. There are 323 other cells and I hadn’t looked at any of them.&lt;/p&gt;

&lt;p&gt;You can walk 324 combinations by hand. But you’d need an afternoon and a lot of coffee, and the first forty are going to make you want to stop. This is where most people quit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Four: Hand the Model the Tedious Part
&lt;/h2&gt;

&lt;p&gt;This is the part of the method a model was born for. Walking a grid is the kind of work nobody finishes by hand, and a model will grind through it without getting bored or skipping cells out of laziness.&lt;/p&gt;

&lt;p&gt;There’s one step to add before the walk, though. Later practitioners of Zwicky’s method added a pass called cross-consistency assessment: go through every &lt;em&gt;pair&lt;/em&gt; of values and cross out the ones that can’t coexist. If nobody filters, there’s no score, so “fixed top N” is meaningless. Any combination containing that pair is dead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvn2vx0fmzrki6853d0hf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvn2vx0fmzrki6853d0hf.jpg" alt="Step Four: Hand the Model the Tedious Part" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the prompt, after the same paragraph describing the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I'm running Zwicky's morphological analysis on this. I've already picked the
parameters and values. Your job is the tedious part.

[the five parameters and their values, as in the table above]

That's 3 x 4 x 3 x 3 x 3 = 324 combinations.

Do this:
1. Cross-consistency first. Go through every PAIR of values across parameters
   and flag the pairs that can't coexist or make no sense together. Explain
   each flag in a few words.
2. Count how many of the 324 combinations survive after removing every
   combination containing a flagged pair.
3. Walk every surviving combination. Give each a one-line description of what
   that system would actually be. Number them.
4. Mark the one combination that describes what I have now with [CURRENT].
5. Pick the five surviving combinations that are furthest from [CURRENT] and
   still buildable by one person in a weekend. For each, say what would change
   and what I'd lose.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the prompt doesn’t ask how to fix my report. It hands over a process I’d already started and tells the model which step I want it to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  What came back
&lt;/h3&gt;

&lt;p&gt;The cross-consistency pass took seconds and found ten conflicting pairs. Most were right. “Model scoring” plus “no cap” got flagged because “you’d be computing a score and then never using it to cut anything.” Fair. “Nobody filters” plus “only when something crosses a bar” got flagged because the bar needs something automated watching it. Also fair. It even flagged one of its own calls as shaky: “A couple of these, like F1, are judgment calls about what ‘keyword rules’ means.”&lt;/p&gt;

&lt;p&gt;It counted 138 survivors out of 324: the ten flagged pairs killed 186 combinations between them.&lt;/p&gt;

&lt;p&gt;Then it was supposed to walk all 138, one line each. It didn’t. It grouped them into 50 “shapes” and collapsed the unit parameter into a bracket, and its excuse was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’m collapsing Unit into a bracket rather than writing three near-identical lines each time; that’s the Zwicky box itself demonstrating your actual problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which is funny. It got handed a list too long to be worth reading, and it clustered it while walking a grid where “cluster of items about the same story” was one of the options for my report.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where it went wrong
&lt;/h3&gt;

&lt;p&gt;Mostly in the pick, and that one’s on me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxfznz4qver66umcbg5hs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxfznz4qver66umcbg5hs.jpg" alt="Where it went wrong" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Furthest from current” was a dumb thing to ask for.&lt;/strong&gt; I asked for the five combinations furthest from what I have, and it gave me exactly that: five combinations that flip all five parameters. Three of the five are keyword filters, which is the weakest filter on the grid. Two of them auto-post to my blog with no review, which is the far end of a row I put there knowing I’d never pick it. Distance from the current cell isn’t the same thing as interesting. I gave it a measurable criterion because measurable felt safe, and it measured.&lt;/p&gt;

&lt;p&gt;The walk was fine. What it missed was meaning: what I actually wanted from the pick, which I never told it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Part You Can’t Hand Over
&lt;/h2&gt;

&lt;p&gt;So I tried the obvious next experiment. Same paragraph about the script, but this time the model picks the parameters too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I want to run Zwicky's morphological analysis on this. Step one only: list the
independent parameters of the problem, and for each, the possible values. Do
not solve anything yet.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It came back with twelve parameters. Purpose, source scope, relevance scoring basis, dedup granularity, output unit, volume control, target size, summarization depth, ordering, human feedback loop, novelty window, cadence. Between four and eight values each.&lt;/p&gt;

&lt;p&gt;That’s roughly 102 million combinations.&lt;/p&gt;

&lt;p&gt;It’s a thorough list, and most of the parameters are real. But it isn’t a Zwicky box. Three things go wrong with it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The parameters aren’t independent.&lt;/strong&gt; “Volume control mechanism” includes “fixed top-N cutoff.” “Target size/length” includes “fixed count (e.g., top 10).” That’s the same thing listed twice. Step one of the method is independence, and the list fails it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One value can’t exist.&lt;/strong&gt; Under the feedback loop it offers “implicit signal capture (what you actually open/click).” The script writes a markdown file and emails it to me. There’s no tracking, no server, nothing that sees a click. That idea came up once already in my planning notes and it dead-ends there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing got cut.&lt;/strong&gt; A list of everything that could vary is easy. Deciding which five things matter for this report isn’t.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I’m not going to pretend it was useless, because its first parameter was better than anything on my list. &lt;strong&gt;Purpose:&lt;/strong&gt; what would “working” even mean? Ambient awareness, triage for research, raw material to write from, a searchable archive, an early warning for a few specific things. I never asked that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fue62ul1ler28uftvx73j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fue62ul1ler28uftvx73j.jpg" alt="The Part You Can't Hand Over" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the division of labor looks like this. The model is good at walking the grid and decent at suggesting things to put on it. Picking the parameters, cutting them down to the few that are independent and yours, and knowing what each value &lt;em&gt;means&lt;/em&gt; is the judgment half, and it doesn’t transfer. The model doesn’t know what I’d do with a better report, and the parameters are where all of that lives.&lt;/p&gt;

&lt;p&gt;I went looking for research on whether decomposition methods like this one work better when you run them with a model, and I couldn’t find anything I’d point you to. There are papers on combining ideas and papers on models converging on the same answers. Nobody seems to have tested the Zwicky box. So this is one run on one problem, and it’s worth exactly that much.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cell I Circled
&lt;/h2&gt;

&lt;p&gt;With the purpose question added, the walk reads differently. This report has one job: keep me up to date on all this AI stuff, and now and then hand me something I haven’t run into, which sometimes turns into a post idea. It’s for me. Every cell that ends in “auto-post to blog” is dead on arrival, and so is every cell that makes me do the filtering, because that’s the one I’m already ignoring.&lt;/p&gt;

&lt;p&gt;The one I circled: &lt;strong&gt;clusters of items about the same story, filtered by similarity to what I’ve clipped into my notes, capped at a top N, daily, in my inbox.&lt;/strong&gt; That’s shape #32 in the model’s walk, with clusters as the unit. And the first answer is still in there: the cap, and a filter that actually cuts. The average answer is a special case of the walk.&lt;/p&gt;

&lt;p&gt;The most useful sentence in the whole model run is about #44, a neighbor of that cell (same filter, a threshold instead of a top N), in the “what you’d lose” section:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;discovery of genuinely new topics (similarity filters reinforce past interests, they don’t surface unknown unknowns)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s true. Half the point of this report is surfacing things I haven’t run into, and a filter built on what I’ve already clipped is going to just create an echo chamber. My report already sorts by exactly that similarity. So the cell needs a small slot for things that &lt;em&gt;don’t&lt;/em&gt; look like my clips. That’s a sixth parameter I didn’t have, and I only found it because the model walked the cells carefully enough.&lt;/p&gt;

&lt;p&gt;I haven’t built it yet. If I don’t start opening that email in the morning, the cell was wrong.&lt;/p&gt;

&lt;p&gt;None of that is the answer I got when I asked how to fix my report. Taking it apart got me a format I never chose, five parts I’d been treating as one, 324 combinations, a purpose I’d never stated, and one cell I’d never have proposed as a whole, because as a whole it sounds like a weird way to read the news.&lt;/p&gt;

&lt;p&gt;Next time you catch yourself asking a model to fix a problem, write down its parts first. Five whys, a list of attributes, a grid of values. You’ll pick the rows yourself, then hand the walk to the machine. It’s the one part of the job it will do all afternoon without complaining.&lt;/p&gt;

</description>
      <category>morphologicalanalysi</category>
      <category>zwickybox</category>
      <category>problemdecomposition</category>
      <category>fivewhys</category>
    </item>
    <item>
      <title>Obsidian Keeps Reloading on My iPad, So I Built a Plugin to Find the Plugins Killing It</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Wed, 04 Nov 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/obsidian-keeps-reloading-on-my-ipad-so-i-built-a-plugin-to-find-the-plugins-killing-it-adc</link>
      <guid>https://dev.to/eristoddle/obsidian-keeps-reloading-on-my-ipad-so-i-built-a-plugin-to-find-the-plugins-killing-it-adc</guid>
      <description>&lt;p&gt;I haven’t opened my Obsidian vault on my iPad in a few months. I could get maybe five or six taps in, open a note, start reading, and the whole thing would reload. About once a minute.&lt;/p&gt;

&lt;p&gt;I knew it was one of my 46 plugins. I also knew the only advice anyone gives for finding it: turn plugins off one at a time until the problem stops. On a device that resets itself every sixty seconds. So I didn’t do that. I burnt some free Kiro credits having it build a plugin to do it for me.&lt;/p&gt;

&lt;p&gt;That plugin didn’t work. Every number on its dashboard was a dash, and its 94 unit tests passed anyway. This post is why that happened, and what my vault looked like once something finally measured it. And then the sync, which is where it all went sideways again.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Your iPad Keeps Reloading Obsidian&lt;/li&gt;
&lt;li&gt;
The Plugin That Measured Nothing

&lt;ul&gt;
&lt;li&gt;How the bugs got found&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How You Measure a Plugin When Everything Shares One Thread&lt;/li&gt;
&lt;li&gt;What My Vault Looked Like Once Something Measured It&lt;/li&gt;
&lt;li&gt;Red Doesn’t Mean Delete&lt;/li&gt;
&lt;li&gt;Getting the Vault Onto the iPad&lt;/li&gt;
&lt;li&gt;It Stopped Reloading. Did the Sync Work?&lt;/li&gt;
&lt;li&gt;Keep It Installed, Keep It Off&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Your iPad Keeps Reloading Obsidian
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnseh79sgez2u25wtsqdm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnseh79sgez2u25wtsqdm.png" alt="Chart of app memory climbing to the iOS limit, the app getting killed, and relaunching, three times in a row" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;iOS gives every app a memory budget, and when Obsidian blows through it, the system kills the app. Obsidian relaunches, loads your plugins, blows through the budget again, and gets killed again. It looks like the app refreshing itself on a timer.&lt;/p&gt;

&lt;p&gt;The Obsidian forum is full of threads describing the same loop: &lt;a href="https://forum.obsidian.md/t/constant-reloads-on-mobile-ios/81780" rel="noopener noreferrer"&gt;constant reloads on iOS&lt;/a&gt;, &lt;a href="https://forum.obsidian.md/t/unable-to-use-mobile-ios-app-as-it-continuously-keeps-loading-and-reloading/82072" rel="noopener noreferrer"&gt;an iOS app that “continuously keeps loading and reloading”&lt;/a&gt;, and an &lt;a href="https://forum.obsidian.md/t/ios-app-stuck-in-restart-loop-after-updating-to-v1-12-4/111733" rel="noopener noreferrer"&gt;iOS restart loop after an update&lt;/a&gt; that one user traced to Omnisearch. In &lt;a href="https://forum.obsidian.md/t/bug-obsidian-window-totally-freezes-on-my-ipad-and-on-iphone-keeps-on-reloading/50926" rel="noopener noreferrer"&gt;another thread&lt;/a&gt;, the person whose iPhone kept reloading had 82 plugins and no idea which one was doing it. No judgment. I have 46. Another user replied that Waypoint had been restarting Obsidian on them. It’s usually the plugins that index your whole vault. Indexing a big vault takes a lot of memory.&lt;/p&gt;

&lt;p&gt;The standard fix is bisecting. Disable half your plugins, see if the loop stops, then disable half of the half, and keep going. There’s a &lt;a href="https://github.com/chrisgrieser/obsidian-divide-and-conquer" rel="noopener noreferrer"&gt;Divide and Conquer plugin&lt;/a&gt; that automates the toggling. It works. It’s also a miserable way to spend an evening with 46 plugins, and it only tells you which plugin crossed the line. It doesn’t tell you how close the rest of them are.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plugin That Measured Nothing
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fru35vjne08be370on12b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fru35vjne08be370on12b.jpg" alt="The Plugin That Measured Nothing" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea was simple. Show me every plugin with how heavy it is, color it red, yellow or green, and give me one button that builds a separate config folder for mobile with the heavy ones stripped out. A setting called Override config folder lets a device read its settings and plugins from a folder other than &lt;code&gt;.obsidian&lt;/code&gt;. My plugin would generate that folder for me.&lt;/p&gt;

&lt;p&gt;This one started the same way as everything in &lt;a href="https://dev.to/eristoddle/the-obsidian-plugin-collection-i-built-one-free-kiro-credit-at-a-time-2b42"&gt;my Obsidian plugin collection&lt;/a&gt;: a one-paragraph idea note and whatever I got for free from Kiro that month. &lt;a href="https://dev.to/eristoddle/how-i-built-two-obsidian-plugins-while-kiro-ai-did-most-of-the-work-40e4"&gt;Kiro wrote a full spec&lt;/a&gt; for it, then built it: a profiler, a compatibility database of known heavy plugins, a recommendations panel, and the config generator. It also wrote the test suite, including property-based tests that ran each check 100 times. My contribution was the idea note and the poking. I guided the building. It counts.&lt;/p&gt;

&lt;p&gt;My quality control for those plugins is the same every time. I develop the plugin in my test vault, poke at it, and give it a label: done messing with it, needs another pass, or back on the shelf. Every load time was a dash. The traffic-light ratings column was empty. The one actual recommendation it made was “Disable Dataview on mobile,” which it got from the hardcoded list. I wrote it off as useless and it went on the shelf.&lt;/p&gt;

&lt;p&gt;Months later I came back to it with Claude Code and asked what was wrong. Poking at it had been the right call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The profiler read from a log Obsidian never writes to.&lt;/strong&gt; It looked up each plugin’s load time with the browser’s Performance API: named timing entries, plus “resource” entries for each plugin’s &lt;code&gt;main.js&lt;/code&gt;. That works for files a web page downloads. Obsidian doesn’t download plugins. It reads &lt;code&gt;main.js&lt;/code&gt; off the disk and runs it, so there’s never a resource entry and never a named entry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tests passed because they tested a fake Obsidian.&lt;/strong&gt; The test suite mocked the &lt;code&gt;obsidian&lt;/code&gt; module, and the mock used timing entries. So the tests proved the code worked against the Obsidian the tests imagined. 94 tests, the property checks running 100 times each: call it 9,400 green checkmarks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fooi1rsw86eufa7y2cmer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fooi1rsw86eufa7y2cmer.png" alt="Diagram comparing a web page download that creates a timing entry, Obsidian loading main.js from disk with no timing entry, and mocked unit tests that pass anyway" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The styles were in the wrong folder.&lt;/strong&gt; Obsidian only loads &lt;code&gt;styles.css&lt;/code&gt; from the root of a plugin’s folder. Kiro put it in &lt;code&gt;src/&lt;/code&gt;. The traffic-light dots had no CSS, so they rendered as nothing, which is why the ratings column looked empty.&lt;/p&gt;

&lt;p&gt;And a bonus one. The config generator copied the &lt;code&gt;.obsidian&lt;/code&gt; folder, including every folder inside every plugin. I build my plugins inside a test vault, so that meant every repo’s &lt;code&gt;node_modules&lt;/code&gt; and &lt;code&gt;.git&lt;/code&gt; history. The “lean” mobile config it generated back in July was 794 MB and 44,347 files. Magnitudes bigger than the desktop config it was supposed to slim down.&lt;/p&gt;

&lt;h3&gt;
  
  
  How the bugs got found
&lt;/h3&gt;

&lt;p&gt;None of this came from reading test output. Obsidian is an Electron app, and Electron apps will open the same debugging port Chrome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;open &lt;span class="nt"&gt;-a&lt;/span&gt; Obsidian &lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="nt"&gt;--remote-debugging-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;9222

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that running, a short Node script can find the window for a specific vault and run JavaScript inside it. That’s how Claude Code checked the real thing instead of the mock. It asked the running app for its plugin list, asked my plugin’s profiler for its numbers, opened the dashboard, clicked its buttons, and read the table back. The answer took seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// run inside the Test vault's window over the DevTools protocol&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;obsidian-mobile-optimizer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;profiler&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collectMetrics&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pluginId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadTimeMs&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="c1"&gt;// every row: [pluginId, null]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;performance.getEntriesByName()&lt;/code&gt; came back empty: zero resource entries, for every plugin. The bug was confirmed in the actual app in about a minute, after the unit tests had spent months saying everything was fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  How You Measure a Plugin When Everything Shares One Thread
&lt;/h2&gt;

&lt;p&gt;The reason this is hard is that Obsidian runs every plugin as JavaScript in one shared process, with one shared pool of memory. A browser can show you per-tab memory because each tab is its own process. Obsidian plugins aren’t, so there’s no “how much RAM is Omnisearch using” number to ask for. There’s an open &lt;a href="https://forum.obsidian.md/t/list-memory-usage-per-plugin-e-g-a-task-manager/103007" rel="noopener noreferrer"&gt;feature request for exactly that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can’t measure a plugin directly. You can measure around it. The rebuilt plugin uses four measurements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh8ypeveebciabcqrwcqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh8ypeveebciabcqrwcqm.png" alt="Diagram of one shared Obsidian process holding all plugins, surrounded by four measurements: bundle size, stored data, load time, and memory" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bundle size.&lt;/strong&gt; Every plugin is a &lt;code&gt;main.js&lt;/code&gt; file, and it gets read into memory at startup. Most of mine are under 150 KB. A couple are over 4 MB. This works on every device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stored data.&lt;/strong&gt; Plugins that build indexes and caches keep them in the app’s built-in IndexedDB database, and they name their databases after themselves: &lt;code&gt;dataview/cache/&amp;lt;vault id&amp;gt;&lt;/code&gt;, &lt;code&gt;omnisearch/cache/&amp;lt;vault id&amp;gt;&lt;/code&gt;, &lt;code&gt;Excalidraw &amp;lt;vault id&amp;gt;&lt;/code&gt;. So the plugin can list the databases, figure out which plugin owns each one, and estimate the size by counting records and sampling a few. I’m hoping it’s the number that should catch the indexing plugins those forum threads keep blaming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load time.&lt;/strong&gt; Turn the plugin off, then time turning it back on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disablePlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enablePlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadTimeMs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the in-memory versions of the calls. They don’t touch &lt;code&gt;community-plugins.json&lt;/code&gt;, so every plugin ends up enabled as it was.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory.&lt;/strong&gt; Read the JavaScript heap before turning the plugin back on and a moment after. The difference is roughly what that plugin added. This only works in Chromium, so desktop and Android, not iOS. It’s also noisy, because garbage collection can land in the middle of a measurement. I’ll get to how noisy.&lt;/p&gt;

&lt;p&gt;With 9757 community plugins, I always look first because odds are I can just install something. When I went looking, I found the load-time half of this already exists. Obsidian has a built-in “Debug startup time” view (the docs on &lt;a href="https://docs.obsidian.md/plugins/guides/load-time" rel="noopener noreferrer"&gt;optimizing plugin load time&lt;/a&gt; cover it), and a community plugin called &lt;a href="https://github.com/hannesdelbeke/obsidian-startup-metrics-logger" rel="noopener noreferrer"&gt;Startup Metrics Logger&lt;/a&gt; runs the same turn-it-off-and-on benchmark mine does. Separate mobile configs aren’t new either. People have been &lt;a href="https://preslav.me/2022/10/17/switch-between-multiple-obsidian-configurations-with-ease/" rel="noopener noreferrer"&gt;setting up Override config folder by hand&lt;/a&gt; for years.&lt;/p&gt;

&lt;p&gt;So I didn’t invent plugin timing. What I couldn’t find anywhere was the stored-data measurement, and something that goes from the numbers to a working mobile config without you copying folders around by hand. That’s the whole plugin. It’s two buttons.&lt;/p&gt;

&lt;h2&gt;
  
  
  What My Vault Looked Like Once Something Measured It
&lt;/h2&gt;

&lt;p&gt;I installed the rebuilt version in my real vault through &lt;a href="https://dev.to/eristoddle/how-to-install-activate-and-update-obsidian-plugins-4d2p"&gt;BRAT&lt;/a&gt;, hit Measure load times, and got this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5rsr3qzn021yblk85dq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5rsr3qzn021yblk85dq.jpg" alt="Mobile Optimizer load-time table for my vault" width="800" height="1742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The worst plugin in my vault is &lt;strong&gt;Novel Word Count&lt;/strong&gt;. It takes 2,133 ms to load and, by the noisiest measurement on the dashboard, adds 105 MB of memory. Nothing else comes close on load time. Dataview is second at 916 ms and tops that noisy memory column at 374 MB. Omnisearch adds 116 MB, Excalidraw 90 MB, same column, same caveat.&lt;/p&gt;

&lt;p&gt;Novel Word Count had also been messing up my vault in other ways. Its whole job is counting. While digging into why the vault was 13.6 GB, I found its plugin folder: 1.7 GB. The plugin is 84 KB. The rest was 579 Dropbox “conflicted copy” versions of its &lt;code&gt;data.json&lt;/code&gt;, going back to September 2024. The plugin rewrites that file every time counts change, the file had grown to several megabytes, and when two devices saved it close together, Dropbox kept both. A plugin that counts for a living had 579 of something in its own folder and never once reported the number. I deleted them.&lt;/p&gt;

&lt;p&gt;Omnisearch showed a dash in the Stored column, and I assumed my database matching was broken. It wasn’t. Its saved index for my vault is empty: zero records in the search index, and the only data in there is my last ten searches. So it’s rebuilding the whole index in memory every time Obsidian starts. On an iPad, that’s every launch. There may be a setting for that. I haven’t gone looking yet. It’s not in the mobile config, so on the iPad there’s no index to rebuild.&lt;/p&gt;

&lt;p&gt;About that memory column. Copy Path shows +57.7 MB. Copy Path copies file paths. That number is garbage collection landing at the wrong moment, not the plugin. Treat the memory column as a hint and the load time and bundle size as the numbers you trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Red Doesn’t Mean Delete
&lt;/h2&gt;

&lt;p&gt;The first rebuilt version made the same mistake the original did. It decided for me. Everything red got stripped from the mobile config, no questions asked.&lt;/p&gt;

&lt;p&gt;And look at Remotely Save in that screenshot. Red. 160 ms to load, a 4.1 MB bundle, 69 MB of memory. By the numbers it should go. It’s also the only reason I wanted Obsidian on the iPad, because it’s how my vault syncs there.&lt;/p&gt;

&lt;p&gt;So now every row has a Mobile checkbox, and the colors only set the defaults. Red starts unchecked, yellow and green checked, and &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-across-all-your-devices-including-free-methods-1mi5"&gt;sync plugins&lt;/a&gt; (Remotely Save, Self-hosted LiveSync, Fit) checked whatever color they are, with a “sync” tag. Your choices are saved, so re-measuring doesn’t wipe them. And there’s a running total at the top. Mine says the mobile config carries 26 of my 46 plugins and 16.7 MB of bundles, against 43.8 MB on desktop.&lt;/p&gt;

&lt;p&gt;I checked off some yellow plugins to keep four of the red ones, but this is all arbitrary anyway.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fge6tvkwf02j9ukcod3y0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fge6tvkwf02j9ukcod3y0.jpg" alt="Mobile Optimizer recommendations list" width="800" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(That’s the Recommendations list, and it’s wrong: I took the screenshot on version 1.2.0, which still told me to disable Remotely Save “(needed for sync)” in the same sentence, and it lists Tasks, Excalidraw and Iconic, which I’d checked to keep. 1.2.1 only lists plugins that are being left off.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting the Vault Onto the iPad
&lt;/h2&gt;

&lt;p&gt;This is the part that’ll trip you up, because Obsidian on iOS hides things in different places than desktop.&lt;/p&gt;

&lt;p&gt;My vault lives in Dropbox. I zipped it there, downloaded the zip with the Dropbox app on the iPad, and extracted it into &lt;strong&gt;On My iPad → Obsidian&lt;/strong&gt;. Obsidian on iOS only opens vaults from inside its own folder. My first attempt was finding the vault folder in Files and choosing “Open with Obsidian,” which doesn’t open it. It imports the files into whatever vault is open.&lt;/p&gt;

&lt;p&gt;Once the vault is in the right place, open the left sidebar, tap the vault name, choose &lt;strong&gt;Manage vaults&lt;/strong&gt; , and open it from the list.&lt;/p&gt;

&lt;p&gt;A newly added vault opens in restricted mode, with all community plugins off. Community plugins then offered me a toggle to “restore 46 previously installed plugins.” I didn’t know what it would do, so I turned it off and exited restricted mode. Every plugin came up disabled.&lt;/p&gt;

&lt;p&gt;Do it in this order and skip that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Leave the restore toggle off. It brings back all 46, which is the desktop setup the mobile config exists to escape.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings → Files and links&lt;/strong&gt; , scroll to the Advanced section at the bottom, and set &lt;strong&gt;Override config folder&lt;/strong&gt; to &lt;code&gt;.obsidian.mobile&lt;/code&gt;. Do it before you leave restricted mode.&lt;/li&gt;
&lt;li&gt;Restart Obsidian: swipe it away in the app switcher, then reopen it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now the iPad reads the mobile config instead of the desktop one. As far as the iPad is concerned, the plugins you didn’t keep don’t exist.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffqt2uzm4ldhdnk4fviz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffqt2uzm4ldhdnk4fviz5.png" alt="Diagram of the desktop .obsidian folder with 46 plugins and 43.8 MB of bundles beside the iPad's .obsidian.mobile folder with 26 plugins and 16.7 MB, plus the Override config folder setting path" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It Stopped Reloading. Did the Sync Work?
&lt;/h2&gt;

&lt;p&gt;With the mobile config loaded, the reloading stopped. After months of not being able to use it, I’ll take it.&lt;/p&gt;

&lt;p&gt;So I turned on Remotely Save, wrote “test” in an old daily note, and waited for it to show up on my Mac.&lt;/p&gt;

&lt;p&gt;It didn’t. Remotely Save’s log had an error about the date on a file called &lt;code&gt;_remotely-save-metadata-on-remote.json&lt;/code&gt;. I checked it on the Mac. Its modified date was December 31, 1969. The file predates Dropbox. It predates Obsidian. It predates the iPad it was refusing to sync to. It’s what the computer says when a timestamp is zero. I refreshed the date on the Mac, downloaded the fixed copy from Dropbox, and replaced the one on the iPad. That error went away.&lt;/p&gt;

&lt;p&gt;The next one didn’t. Remotely Save stopped with “too many errors” after a pile of these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Dropbox does not support emoji in file / folder names.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That isn’t iOS, and it isn’t my file system. It’s a rule in Remotely Save’s own Dropbox code (version 0.5.25), which refuses to create any folder or upload any file with an emoji in the path. I use emoji in file and folder names. It’s part of how the vault is organized now. And the same vault, emoji and all, already syncs through Dropbox between two Macs without complaint. So this is Remotely Save being stricter than Dropbox needs it to be.&lt;/p&gt;

&lt;p&gt;I wrote a whole post on &lt;a href="https://dev.to/eristoddle/obsidian-dropbox-sync-a-setup-guide-2ajl"&gt;setting up Obsidian Dropbox sync with Remotely Save&lt;/a&gt;, and my &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-on-iphone-and-ipad-for-free-in-2026-427p"&gt;guide to syncing Obsidian on iPhone and iPad for free&lt;/a&gt; says I run Dropbox with Remotely Save on my iPad. The point of fixing the crash was to get that sync back. The plugin fixed the crash. The sync it was all for is still broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep It Installed, Keep It Off
&lt;/h2&gt;

&lt;p&gt;Where this leaves things: the iPad opens my vault and doesn’t reload. Sync from the iPad doesn’t work yet, because of the emoji rule. &lt;a href="https://dev.to/eristoddle/remotely-save-for-obsidian-s3-and-webdav-sync-that-costs-0-on-r2-1gfh"&gt;Remotely Save is open source&lt;/a&gt;, and that check is a few lines of code, so a pull request is on the someday list right next to everything else.&lt;/p&gt;

&lt;p&gt;The plugin doesn’t need to stay on. It’s about 14 KB and does nothing until you open its dashboard, and your keep-on-mobile choices are saved in its settings. So the routine is: enable it, measure, adjust the checkboxes, generate, and disable it. Run it when you install new plugins, because one of them is going to be the next Novel Word Count.&lt;/p&gt;

&lt;p&gt;It’s on GitHub at &lt;a href="https://github.com/eristoddle/obsidian-mobile-optimizer" rel="noopener noreferrer"&gt;eristoddle/obsidian-mobile-optimizer&lt;/a&gt;. Install it with &lt;a href="https://github.com/TfTHacker/obsidian42-brat" rel="noopener noreferrer"&gt;BRAT&lt;/a&gt; by adding &lt;code&gt;eristoddle/obsidian-mobile-optimizer&lt;/code&gt;. If your iPad has been reloading Obsidian at you for months, measure first. Bisect only if you still need to.&lt;/p&gt;

</description>
      <category>obsidianipad</category>
      <category>obsidianplugin</category>
      <category>ipadmemory</category>
      <category>pluginmanagement</category>
    </item>
    <item>
      <title>Gemini 4 Carbon Is #1, and You Can't Use It</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 03 Nov 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/gemini-4-carbon-is-1-and-you-cant-use-it-5473</link>
      <guid>https://dev.to/eristoddle/gemini-4-carbon-is-1-and-you-cant-use-it-5473</guid>
      <description>&lt;p&gt;Google announced Gemini 4 Carbon on October 28, and by the end of the week it was the top model on both boards I track. It leads four of Arena’s six main categories and sits first on the Artificial Analysis Intelligence Index with a 59. You can’t use it. Google is giving it to “a subset of cyber defenders” through something called the Fairwind program, and everybody else gets it “as soon as possible.”&lt;/p&gt;

&lt;p&gt;So the best model in the world this week is a press release with a leaderboard attached. And it still managed to rearrange my cheapskate table. When the leader goes up, the 50-point cutoff goes up with it, and two of last week’s 50-cent picks fell off the edge without moving a single point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Gemini 4 Carbon: number one, behind a velvet rope

&lt;ul&gt;
&lt;li&gt;What the scores say&lt;/li&gt;
&lt;li&gt;What it costs, if you could buy it&lt;/li&gt;
&lt;li&gt;The reaction&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The rest of the board&lt;/li&gt;
&lt;li&gt;
The cheapskate table

&lt;ul&gt;
&lt;li&gt;A model you can’t buy knocked out two picks&lt;/li&gt;
&lt;li&gt;The table you can actually buy from&lt;/li&gt;
&lt;li&gt;Line calls&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Local sweet spot&lt;/li&gt;
&lt;li&gt;
Horror stories

&lt;ul&gt;
&lt;li&gt;A backdoored Claude Code extension, served by Cursor&lt;/li&gt;
&lt;li&gt;The ten-minute first token&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What’s coming&lt;/li&gt;
&lt;li&gt;Finally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gemini 4 Carbon: number one, behind a velvet rope
&lt;/h2&gt;

&lt;p&gt;Google calls Carbon its next frontier model, “building on Gemini 4 Argon,” which went GA only two weeks ago. Google hasn’t said whether it’s a new training run or a later checkpoint. Before launch, a Google employee reportedly called it “the next Gemini Pro model,” &lt;a href="https://letsdatascience.com/news/gemini-4-carbon-checkpoint-reportedly-appears-on-chatbot-are-ee165ebf" rel="noopener noreferrer"&gt;per Let’s Data Science&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The pitch is cybersecurity and long-running tasks. &lt;a href="https://www.theregister.com/a/5306149" rel="noopener noreferrer"&gt;The Register&lt;/a&gt; quotes Google’s Koray Kavukcuoglu: “On internal benchmarks, Carbon achieves more than 2x uplift in success rate for generating secure code over Argon.” That’s also the reason for the gated launch. A model that finds and patches vulnerabilities this well is just as handy for someone who wants to exploit them, so defenders go first and Google is taking part in the U.S. government’s voluntary pre-release testing.&lt;/p&gt;

&lt;p&gt;Last week I wrote about Moonshot handling the same problem by cutting the cyber data out of Kimi K3.1 Pro’s open weights. Google kept the capability and locked the door. Both approaches end up with the same thing for you and me this week: no access.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the scores say
&lt;/h3&gt;

&lt;p&gt;The independent scores hold up. On &lt;a href="https://artificialanalysis.ai/articles/gemini-4-carbon-new-number-1" rel="noopener noreferrer"&gt;Artificial Analysis&lt;/a&gt;, Carbon at high effort scores 59 on the new Intelligence Index v5.0, one point over Claude Opus 5.5 at max (58) and two over GPT-6 Astra at max (57). It takes first place on four of AA’s nine evaluations. On LMArena it’s first in Overall (1527.51), Coding (1573.45), Instruction Following (1524.64) and Hard Prompts (1548.17).&lt;/p&gt;

&lt;p&gt;Not many people have voted yet, though. Carbon has 4,403 Overall votes and 1,106 in Coding. Last week I watched Argon lose 6.7 Overall points as its vote count doubled, so expect some of Carbon’s lead to leak away the same way.&lt;/p&gt;

&lt;p&gt;The launch table is mostly Google’s own work: 65.2 percent on Terminal-Bench 4.0 against 59.6 for Opus 5.5, 88.2 percent on SEC-bench Pro, 54.8 percent on ExploitGym against Argon’s 42.0. It doesn’t win everything even on Google’s own chart. GPT-6 Astra leads FrontierSWE 2 (65.5 to 61.2), and Opus 5.5 leads OSWorld-2.1 (87.2 to 81.5). AA also has it behind several models on its AA-Briefcase knowledge-work test, with an 11 percent hallucination rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it costs, if you could buy it
&lt;/h3&gt;

&lt;p&gt;The list price is $4 in and $20 out, with a 50 percent launch discount that makes it $2/$10, the same deal Argon got. Argon’s discount ends November 30. AA says Carbon’s has “no confirmed end date.”&lt;/p&gt;

&lt;p&gt;AA puts one of its index tasks at $7.76 on Carbon at high effort. That’s about 23 percent under Opus 5.5 at max ($10.04), because Carbon writes 123,000 output tokens per task against Opus’s 173,000. Here’s how the top of &lt;a href="https://artificialanalysis.ai/leaderboards/models" rel="noopener noreferrer"&gt;AA’s board&lt;/a&gt; looks on cost:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model and effort&lt;/th&gt;
&lt;th&gt;AA Index (v5.0)&lt;/th&gt;
&lt;th&gt;Cost per AA task&lt;/th&gt;
&lt;th&gt;Time to first token&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 4 Carbon, high&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;$7.76&lt;/td&gt;
&lt;td&gt;147.83s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 4 Carbon, medium&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;$6.59&lt;/td&gt;
&lt;td&gt;29.12s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5.5, max&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;$10.04&lt;/td&gt;
&lt;td&gt;625.92s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6 Astra, max&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;$6.24&lt;/td&gt;
&lt;td&gt;368.87s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 5.5, xhigh&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;td&gt;$6.05&lt;/td&gt;
&lt;td&gt;110.35s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol, max&lt;/td&gt;
&lt;td&gt;55&lt;/td&gt;
&lt;td&gt;$1.27&lt;/td&gt;
&lt;td&gt;307.83s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 4 Argon, high&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;$7.68&lt;/td&gt;
&lt;td&gt;40.47s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Carbon at medium gives up one point to save $1.17 a task and starts answering five times sooner. And GPT-6.1 Sol at max scores 55 for $1.27. Carbon’s extra four points cost six times as much.&lt;/p&gt;

&lt;p&gt;Argon at high scores 50 for $7.68 a task. Carbon gets nine more points for eight more cents. Google is replacing Argon with something much better at almost the same per-task price, which is a nice move if it ever ships.&lt;/p&gt;

&lt;p&gt;AA moved to Index v5.0 this week and rescaled everything. GLM-5.3-Flash went from 42 to 28, Kimi K3.1 Pro from 55 to 46, Argon from 53 to 50, and none of those models changed. Don’t compare this week’s AA numbers with anything I printed before.&lt;/p&gt;

&lt;h3&gt;
  
  
  The reaction
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://news.ycombinator.com/item?id=50277575" rel="noopener noreferrer"&gt;Hacker News launch thread&lt;/a&gt; hit 1,018 points and 804 comments, and the top complaints were about access, not quality. One commenter wrote that “showing benchmarks without releasing the model is quite meaningless.” Another said that if a Google PM handed them $100 to figure out how to prompt Gemini 4 Argon, they were “only ~30% sure” they could pull it off, since the Gemini app on their phone only showed 3.8 Pro.&lt;/p&gt;

&lt;p&gt;On the thread for AA’s write-up, someone using Argon on Google’s Pro plan &lt;a href="https://news.ycombinator.com/item?id=50288524" rel="noopener noreferrer"&gt;reported&lt;/a&gt; that five messages on medium effort was enough to trigger a four-hour cooldown. That’s one person’s report, but it lines up with the app-limit complaints that showed up the week Argon went GA. And then the shortest review of the week: “&lt;a href="https://news.ycombinator.com/item?id=50288858" rel="noopener noreferrer"&gt;Doesn’t mean jack without access to it.&lt;/a&gt;”&lt;/p&gt;

&lt;p&gt;Reddit was more excited. r/singularity’s “Gemini 4 Carbon” post pulled 1,627 points, and r/GeminiAI had “Gemini 4 Carbon is #1 and Elon congratulates Demis” at 1,579. Polymarket gives it a 99 percent chance of release by December 31. That’s a low bar.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the board
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://openrouter.ai/rankings" rel="noopener noreferrer"&gt;OpenRouter’s&lt;/a&gt; week through November 2 belongs to DeepSeek again. V4.1 Flash 1017 did 50.4 trillion tokens, up 43 percent, and the original V4.1 Flash slid 13 percent to 15.1 trillion. DeepSeek now has 29.8 percent of all text requests on the platform. The 1017 snapshot runs $0.15/$0.60 from DeepSeek, scores 32 on AA’s new scale at max for 60 cents a task, and streams at 174 tokens a second. A Hacker News commenter says it “does whole projects and asks for $0.10 on US provider with ZDR on Openrouter,” and that they talked a few friends out of their $20 Claude subscriptions. Arena still hasn’t rated it, so it can’t compete in the table yet.&lt;/p&gt;

&lt;p&gt;GLM-5.3-Flash is second at 15.3 trillion, up 11 percent. People keep paying for it, and it still lost two spots in my table this week.&lt;/p&gt;

&lt;p&gt;MiniMax M3.1 Flash played out about how I guessed last week. The free version, which was fourth at 12.6 trillion, is gone from OpenRouter’s list. The paid version climbed to seventh with 6.46 trillion, up 340 percent. Add the old paid traffic back in and less than half of it stayed once everyone had to pay $0.15/$0.60. The reviews are mixed. The top comment on the &lt;a href="https://news.ycombinator.com/item?id=50157109" rel="noopener noreferrer"&gt;HN launch thread&lt;/a&gt; calls it “pretty benchmaxed,” saying “in actual use, it doesn’t survive the comparison to models in the benchmark.” MiniMax says the weights “will be released later.”&lt;/p&gt;

&lt;p&gt;A few other things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Particle-1, from Particle AI, topped New &amp;amp; Trending with 77.2 billion tokens in its first week. It’s a coding model post-trained on DeepSeek V4.1 Flash, priced at $0.05/$0.50.&lt;/li&gt;
&lt;li&gt;Google’s share of OpenRouter requests dropped 32 percent in a week, to 14.4 percent. The chart doesn’t say why, and Google’s best model this week isn’t something OpenRouter can serve anyway.&lt;/li&gt;
&lt;li&gt;Mistral shipped the Large 4 weights on October 29. One pre-release report had said October 27, so it slipped a couple of days, but it beat its own end-of-October promise. It’s &lt;a href="https://pasqualepillitteri.it/en/news/28041/mistral-large-4-le-chonk-open-weights-hugging-face" rel="noopener noreferrer"&gt;1.05 trillion parameters with 52 billion active&lt;/a&gt;, in FP8, under a modified MIT license Mistral calls the Ecosystem Open-Weight license. Arena has it 113th Overall, and on AA the best Chinese open models still score higher. It leads among Western open models, which is the reason to download it.&lt;/li&gt;
&lt;li&gt;OpenClaw is fourth on OpenRouter’s app list at 840 billion tokens, behind Hermes Agent, Claude Code, and Portkey.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kimi K3.1 Pro, GPT-6.1 Terra, DeepSeek 1017, and MiniMax M3.1 Flash are all still waiting for Arena ratings. The board I used was published October 28.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheapskate table
&lt;/h2&gt;

&lt;p&gt;How this works, if you’re new: in each Arena category, the cutoff is the leader’s rating minus 50, and the pick is the cheapest model above it. The band gets computed in code over every row in &lt;a href="https://huggingface.co/datasets/lmarena-ai/leaderboard-dataset" rel="noopener noreferrer"&gt;LMArena’s leaderboard dataset&lt;/a&gt;, and I record the first model below the line to prove nothing got cut off. Prices are the maker’s own OpenRouter endpoint. Carbon and Argon are at their $10 intro price.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;gemini-4-carbon-high (1528)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Pro (1480, #29)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;−48&lt;/td&gt;
&lt;td&gt;11.5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;gemini-4-carbon-high (1573)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1526, #28)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−47&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-opus-5.5-high (1520)&lt;/td&gt;
&lt;td&gt;$20&lt;/td&gt;
&lt;td&gt;gemini-3.7-flash-high (1490, #6)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−31&lt;/td&gt;
&lt;td&gt;5.3×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;gemini-4-carbon-high (1525)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;DeepSeek-V4.1-Flash 0910 (1477, #26)&lt;/td&gt;
&lt;td&gt;$1.20&lt;/td&gt;
&lt;td&gt;−48&lt;/td&gt;
&lt;td&gt;8.3×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;gemini-4-carbon-high (1548)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1502, #31)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−46&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1532)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1503, #16)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−29&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Band depths: Overall 30, Coding 29, Creative 17, Instruction Following 29, Hard Prompts 37, Math 36. Last week Overall was 49 deep and Coding was 76.&lt;/p&gt;

&lt;h3&gt;
  
  
  A model you can’t buy knocked out two picks
&lt;/h3&gt;

&lt;p&gt;GLM-5.3-Flash didn’t change. Its Overall rating is 1476.52 on 41,642 votes, more votes than any other pick. Carbon set the Overall cutoff at 1477.51, and GLM missed it by 0.99. In Instruction Following it missed by 0.38. Last week it held four categories. This week it holds three, and it lost the other two to a model almost nobody can call.&lt;/p&gt;

&lt;p&gt;This is the mirror image of last week, when Argon sagged and the bands got wider. Carbon pushed the ceiling up, so the bands got narrower. If Carbon’s rating drifts down the way Argon’s did, GLM probably comes back without doing anything.&lt;/p&gt;

&lt;p&gt;The new Overall pick is MiMo-V2.6-Pro at 87 cents, 11.5 times cheaper than Carbon’s intro price. It’s thin on votes (4,037) and slow (44 tokens a second on AA). On AA’s new scale it actually beats GLM on both score and price per task: 30 for 26 cents against 28 for 58 cents. For benchmark-style work it would have been worth a look even if GLM had stayed in.&lt;/p&gt;

&lt;p&gt;Instruction Following goes to DeepSeek V4.1 Flash at $1.20, with an asterisk: the rated model is the September 10 snapshot, and DeepSeek’s own endpoint now serves the 1017 snapshot instead, which is cheaper ($0.60 out) and not rated. I priced the rated model at the $1.20 standard rate the big third-party hosts charge.&lt;/p&gt;

&lt;p&gt;MiMo-V2.6-Flash’s four-issue run as the Coding pick is over too. At 1509.85 it’s nowhere near Carbon’s 1523.45 cutoff. GLM-5.3-Flash takes Coding at 50 cents, 2.65 points over the line.&lt;/p&gt;

&lt;h3&gt;
  
  
  The table you can actually buy from
&lt;/h3&gt;

&lt;p&gt;Carbon leads four categories, and you can’t send it a single request. So here’s the same method with Carbon taken out, the way I ran Argon back when it was gated:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader (ex-Carbon)&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1520)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1477, #32)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;claude-opus-4.7-high (1551)&lt;/td&gt;
&lt;td&gt;$25&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Flash (1510, #59)&lt;/td&gt;
&lt;td&gt;$0.28&lt;/td&gt;
&lt;td&gt;89×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1525)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;DeepSeek-V4.1-Flash 0910 (1477)&lt;/td&gt;
&lt;td&gt;$1.20&lt;/td&gt;
&lt;td&gt;8.3×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1544)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1502)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Creative Writing and Math don’t change, since Carbon doesn’t lead them. Without Carbon, the Overall band is 47 deep and Coding is 78. Coding’s leader becomes Claude Opus 4.7 at $25 out, which is why MiMo-V2.6-Flash’s ratio jumps to 89×.&lt;/p&gt;

&lt;p&gt;I’d pick from this second table today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Line calls
&lt;/h3&gt;

&lt;p&gt;Every category had an edge case under a point this week, and since I don’t round, each one decided something:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Math’s first model out, Qwen3.7-Max-Preview, missed by 0.02 points.&lt;/li&gt;
&lt;li&gt;In Instruction Following, Muse Spark 1.2 made it in by 0.03, and GLM-5.3-Flash missed by 0.38.&lt;/li&gt;
&lt;li&gt;Hard Prompts’ first model out, Claude Opus 4.5, missed by 0.10. DeepSeek V4.1 Flash is in by 0.56.&lt;/li&gt;
&lt;li&gt;Coding’s first model out, Qwen3.7-Max-Preview again, missed by 0.13.&lt;/li&gt;
&lt;li&gt;Creative Writing’s first model out, GPT-5.6 Sol, missed by 0.16.&lt;/li&gt;
&lt;li&gt;GLM-5.3-Flash missed Overall by 0.99.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creative Writing still has no cheap answer. Its 17-model band bottoms out at $3.75 with the Gemini Flash family ($1.875 if you use the flex tier). And December 1 is still on the calendar for Argon going to $4/$20, which doubles every Argon-led ratio in that second table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local sweet spot
&lt;/h2&gt;

&lt;p&gt;Each row gets the biggest model that fits with room to spare for context and still runs at 15 tokens a second or better. Arena rating decides, and when two models land within 15 points of each other, the Artificial Analysis score breaks the tie.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your machine&lt;/th&gt;
&lt;th&gt;Pick&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Arena&lt;/th&gt;
&lt;th&gt;AA&lt;/th&gt;
&lt;th&gt;Measured tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mac 16GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;27 (n=4, 6-82)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 32GB&lt;/td&gt;
&lt;td&gt;qwen3.8-27b MLX 4bit&lt;/td&gt;
&lt;td&gt;16.1 GB&lt;/td&gt;
&lt;td&gt;1436 (#106)&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 64GB+&lt;/td&gt;
&lt;td&gt;gemma-4-31b Q4_K_M&lt;/td&gt;
&lt;td&gt;18.3 GB&lt;/td&gt;
&lt;td&gt;1452 (#77)&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 12GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;50 (n=1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 24GB&lt;/td&gt;
&lt;td&gt;gemma-4-31b Q4_K_M&lt;/td&gt;
&lt;td&gt;18.3 GB&lt;/td&gt;
&lt;td&gt;1452 (#77)&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Nothing changed. I checked the open models that newly surfaced on the board this week (Muse Glimmer, Qwen3.5-27B, Inkling-Small, Qwen3-Next-80B-A3B), and they all rate below Gemma 4 31B on Arena. The AA column is still on the old v4.3.2 scale, since I haven’t rebased the registry to v5.0 yet. The 9B rows are picked by fit, because nothing that small has an Arena rating, and the Gemma speeds stay unmeasured until someone posts a real benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horror stories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A backdoored Claude Code extension, served by Cursor
&lt;/h3&gt;

&lt;p&gt;On October 29, for about 11 hours, Cursor’s own extension marketplace served a tampered build of the Claude Code extension. &lt;a href="https://dev.to/sam_hiotis_117598dbfa3ac2/official-claude-code-extension-on-cursor-marketplace-trojanized-with-persistent-ssh-backdoor-2afl-temp-slug-1356097"&gt;The Hacker News&lt;/a&gt; has the details. Versions 2.1.313 (and 2.1.312, per Cursor’s revised notice) added an attacker’s key labeled “svc-telemetry” to &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;, tried to turn on SSH, opened a reverse tunnel, and set up persistence through a scheduled task, a crontab entry, or a LaunchAgent depending on the OS. It also sent an unencrypted beacon home with your IP, hostname, username, git email, and the names (not the values) of up to 40 environment variables containing words like KEY, TOKEN, SECRET, or AWS.&lt;/p&gt;

&lt;p&gt;Cursor says it hit “at most 5,000 users” and that the build “was not developed by Anthropic.” Anthropic says it “only impacts Cursor users.” The copies on Open VSX and Microsoft’s marketplace were clean. Nobody has said how the attacker got into Cursor’s marketplace.&lt;/p&gt;

&lt;p&gt;Microsoft’s warning is the part to act on: “Removing or updating the extension does not remove artifacts written outside its installation directory.” Updating to 2.1.314 leaves the SSH key and the persistence entries right where they were. If you use Claude Code inside Cursor, run &lt;code&gt;cursor --list-extensions --show-versions | grep -i claude-code&lt;/code&gt;, check &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; for keys you don’t recognize, look through your cron jobs, LaunchAgents, and scheduled tasks, and rotate any credentials that machine could reach. &lt;a href="https://tech-insider.org/claude-code-extension-cursor-5000-users-tampered-2026/" rel="noopener noreferrer"&gt;Tech Insider&lt;/a&gt; links Cursor’s macOS cleanup script. Read it before you run it.&lt;/p&gt;

&lt;p&gt;Last week’s horror story was an AGENTS.md sitting in a Downloads folder, and this week the extension itself was poisoned. Your coding agent has your shell, your keys, and your repo, so anything in its supply chain gets them too.&lt;/p&gt;

&lt;h3&gt;
  
  
  The ten-minute first token
&lt;/h3&gt;

&lt;p&gt;That AA table has a column most people skip. Opus 5.5 at max effort takes 625.92 seconds, a little over ten minutes, to produce its first token. GPT-6 Astra at max takes six minutes, and Carbon at high takes almost two and a half. If you crank the effort dial on an agent loop to get the top score, you’re also signing up for coffee breaks between steps. Carbon at medium (29 seconds), Opus at high (43.54) and Astra at medium (6.03) give up a few points and come back before you’ve stood up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming
&lt;/h2&gt;

&lt;p&gt;Moonshot’s Kimi K3.1 Pro weights are due tomorrow, November 4, with the cyber data cut out and still no license announced. Artificial Analysis lists it as proprietary, and OpenRouter calls it open-weight, so the license will settle that argument. Carbon’s wider rollout has no date beyond “as soon as possible.” Argon goes to $4/$20 on December 1, and Carbon’s discount has no announced end.&lt;/p&gt;

&lt;p&gt;Arena should get to Kimi K3.1 Pro, GPT-6.1 Terra, DeepSeek 1017 and MiniMax M3.1 Flash any day now, and the last two have the best shot at landing in a band. Claude Fable 5.5 is still speculation, and this week’s only source traces back to an October 2 post on X that said “5.5 &amp;gt; 6.1.” I found nothing new on DeepSeek V5. And Mistral’s weights shipped, so that one’s off the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;Use the second table. GLM-5.3-Flash at 50 cents still covers Overall, Hard Prompts and Math once you remove the model nobody can call. MiMo-V2.6-Flash at 28 cents still holds Coding, and if you care more about hard benchmarks than chat polish, try MiMo-V2.6-Pro at 87 cents. If you need frontier-grade work from something with a public API, GPT-6.1 Sol at max scored 55 for $1.27 a task on AA, against $7.76 for Carbon.&lt;/p&gt;

&lt;p&gt;Next week I’ll be watching three things: whether Carbon’s Arena lead holds up as the votes come in, whether the Kimi weights show up with a real license, and whether DeepSeek 1017 finally gets a rating and lands in the table it’s been dominating by volume for two weeks.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
      <category>modelroundup</category>
      <category>largelanguagemodels</category>
    </item>
    <item>
      <title>BMAD, Spec Kit, Superpowers, OpenSpec: Which Agent Skill Framework Fits Your Project Size</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 29 Oct 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/bmad-spec-kit-superpowers-openspec-which-agent-skill-framework-fits-your-project-size-2l17</link>
      <guid>https://dev.to/eristoddle/bmad-spec-kit-superpowers-openspec-which-agent-skill-framework-fits-your-project-size-2l17</guid>
      <description>&lt;p&gt;I planned my last big project up front, before a single line of code existed. The full BMAD process: product brief, PRD, architecture, stories. I slow played the first quarter of the project over about 4 evenings or eight hours, stupidly using Opus to execute the plan. Then I pointed Sonnet at the plan and it built about 75% of the app in one afternoon. A working Electron app, not a demo. Every decision it would have stopped to ask about was already written down somewhere, so it kept going. I am using the app right now to write this post and making notes on the new plugins I’m going to create for it.&lt;/p&gt;

&lt;p&gt;Now I want that on purpose, at scale. I have &lt;a href="https://dev.to/the-great-vibe-coding-experiment/"&gt;a pile of projects in various states of done&lt;/a&gt;, and I want them planned well enough that agents can run them unattended while I do other things, but the projects are not the same. Some are big apps like that one. Some are tiny backend APIs that still need structure. A product brief for a small API is like hiring a general contractor to hang a picture frame.&lt;/p&gt;

&lt;p&gt;So which planning framework fits which project? There are a lot of them: BMAD, Spec Kit, OpenSpec, Superpowers, Matt Pocock’s skills, Addy Osmani’s agent-skills, PStack, plus skill catalogs full of more. Instead of guessing, I sent a research subagent out to map the field, the same trick I wrote about in the &lt;a href="https://dev.to/eleven-deep-research-tools-that-live-inside-your-coding-agent-and-the-one-i-forked/"&gt;deep research tools post&lt;/a&gt;. Nine candidates I named up front. Sixteen more the research found. This post is what that turned into.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The Heavyweights: BMAD and PStack

&lt;ul&gt;
&lt;li&gt;BMAD Method&lt;/li&gt;
&lt;li&gt;PStack&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The Middleweights: Superpowers, Spec Kit, Pocock, and Addy Osmani

&lt;ul&gt;
&lt;li&gt;Superpowers&lt;/li&gt;
&lt;li&gt;Spec Kit&lt;/li&gt;
&lt;li&gt;Matt Pocock’s skills&lt;/li&gt;
&lt;li&gt;Addy Osmani’s agent-skills&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The Lightweights: OpenSpec and the Catalogs

&lt;ul&gt;
&lt;li&gt;OpenSpec&lt;/li&gt;
&lt;li&gt;The catalogs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Ones Research Found&lt;/li&gt;
&lt;li&gt;The Size Chart&lt;/li&gt;
&lt;li&gt;The Gap: Nobody Built the API-Only One&lt;/li&gt;
&lt;li&gt;What I’m Doing With This&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Heavyweights: BMAD and PStack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  BMAD Method
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/bmad-code-org/BMAD-METHOD" rel="noopener noreferrer"&gt;BMAD&lt;/a&gt; is the one I used, and it covers the widest span of anything in this post: research, product brief, PRFAQ (press-release-plus-FAQ), PRD, UX design, architecture, stories, build, review, retro. It ships persona agents (analyst, architect, dev, PM, product owner, UX designer) and it spells out, better than the rest, when a change deserves the full pipeline and when to skip it. A build session is about 500 changed lines in a handful of files. Trivial edits skip BMAD. PRDs are for when more than one person has to agree.&lt;/p&gt;

&lt;p&gt;Install is &lt;code&gt;npx bmad-method install&lt;/code&gt; for the stable v6.12. The V7 preview alpha installs differently (&lt;code&gt;npx skills add bmad-code-org/BMAD-METHOD&lt;/code&gt;), and the alpha docs warn about breaking changes between updates, so maybe don’t build your whole company’s process on it yet. There are add-ons growing around it: BMAD Loop, which builds, verifies, and retros a whole epic unattended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwi9xvko0mvaq4sh6g070.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwi9xvko0mvaq4sh6g070.jpg" alt="BMAD Method" width="800" height="447"&gt;&lt;/a&gt;The critics do have a point though. People call it cumbersome and rigid, and one vendor benchmark (&lt;a href="https://uvik.net/blog/spec-driven-development-benchmark" rel="noopener noreferrer"&gt;Uvik’s SDD benchmark&lt;/a&gt;, 50 tickets) found spec creation used over 40% of the tokens. It is the heaviest thing here to learn. It worked for me because the project was big enough to need all of it. That is the trick with BMAD: match the ceremony to the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  PStack
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/cursor/plugins/tree/main/pstack" rel="noopener noreferrer"&gt;PStack&lt;/a&gt; is Lauren Tan’s (poteto) skill set. It lives inside the cursor/plugins repo, works in Claude Code through the plugin marketplace, and its pitch is “write less, but higher quality code.” More than 50 skills, plus a &lt;code&gt;/poteto-mode&lt;/code&gt; command that matches your task to one of 23 playbooks: investigation, bug fix, perf, feature, refactoring, prototype, babysit, shipping, autonomous run, orchestrate, autopilot.&lt;/p&gt;

&lt;p&gt;The unattended claims are the strongest in the field. The orchestrate playbook runs multi-day fleets of subagents landing stacked PRs, and the README includes the sentence “i’m going to bed. land the stack even if ci flakes.” It splits models by default: grok for code delegates, opus for the hardest changes and prose. It does not do product. No PRD, no market research, no UX phase. It assumes you already know what you are building. Fit: mid to large, experienced-engineer workflow, especially if you use stacked PRs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Middleweights: Superpowers, Spec Kit, Pocock, and Addy Osmani
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Superpowers
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/obra/superpowers" rel="noopener noreferrer"&gt;Superpowers&lt;/a&gt; calls itself a complete software development methodology: 15 auto-triggering skills, installable from the official Claude marketplace (&lt;code&gt;/plugin install superpowers@claude-plugins-official&lt;/code&gt;), supporting about 16 agent harnesses. The flow: brainstorm, git worktree, plan broken into 2-to-5-minute tasks with exact paths and code, subagent-driven execution with a two-stage review, and enforced TDD. It deletes code written before tests, and none of the workflow is optional.&lt;/p&gt;

&lt;p&gt;Its README says it is not uncommon for the agent to work autonomously for a couple hours without deviating from the plan. The web-reported downside is the token bill: the workflow spends tokens before any code exists, and users call it bloated and the full loop overkill on a one-file fix. Sweet spot: small backend to mid app. Skip it for tiny edits (its own docs say the same).&lt;/p&gt;

&lt;h3&gt;
  
  
  Spec Kit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/github/spec-kit" rel="noopener noreferrer"&gt;Spec Kit&lt;/a&gt; is GitHub’s entry: a Python CLI (&lt;code&gt;uv tool install specify-cli&lt;/code&gt;, then &lt;code&gt;specify init my-project --integration copilot&lt;/code&gt;) with 30-plus agent integrations. The flow: set a constitution once per project, then per feature you run specify, plan, tasks, implement, and converge until it says “Converged.” The constitution is the interesting part. It is the strongest governance story in the field: org standards, presets, air-gapped support. If your company needs every agent to follow the same rules, this is the one built for that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2d570b9rulaqtj3rek5m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2d570b9rulaqtj3rek5m.jpg" alt="Spec Kit" width="800" height="447"&gt;&lt;/a&gt;&lt;a href="https://blog.scottlogic.com/2025/11/26/putting-spec-kit-through-its-paces-radical-idea-or-reinvented-waterfall.html" rel="noopener noreferrer"&gt;Scott Logic&lt;/a&gt; put Spec Kit through its paces and found the process rigid, the docs dense, and no qualitative benefit to justify the overhead. (I hit the same wall &lt;a href="https://dev.to/the-third-attempt-how-a-living-plan-beat-both-vibe-coding-and-spec-kit/"&gt;when I tried Spec Kit on a solo project&lt;/a&gt;.) The Uvik benchmark is the useful one: specs help on tickets touching three or more files and do almost nothing for one-to-two-file tickets. That is the thesis of this post in one sentence. Overkill for tiny. Mid to large greenfield, especially with a team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Matt Pocock’s skills
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mattpocock/skills" rel="noopener noreferrer"&gt;Matt Pocock’s repo&lt;/a&gt; is called “Skills For Real Engineers,” and the README positions against GSD (get-shit-done), BMAD, and Spec Kit, accusing them of owning the process, taking away your control, and making bugs in the process hard to resolve. So: the anti-framework framework. Small composable skills instead of a pipeline. &lt;code&gt;claude plugin install mattpocock-skills@claude-plugins-official&lt;/code&gt; or &lt;code&gt;npx skills@latest add mattpocock/skills&lt;/code&gt;, then &lt;code&gt;/setup-matt-pocock-skills&lt;/code&gt; once per repo.&lt;/p&gt;

&lt;p&gt;Its flow is grill (&lt;a href="https://dev.to/my-planning-doc-claimed-to-record-decisions-it-had-two/"&gt;a skill that interrogates you to align&lt;/a&gt;), to-spec, to-tickets (tracer-bullet tickets with blocking edges), then implement or implement-spec, with tdd and code-review. The standouts are wayfinder, which plans work bigger than one agent session can hold as a map of decision tickets, and implement-spec, which runs a whole spec on one integration branch with parallel implementer subagents. The human alignment is front-loaded, which is either the point or the annoyance, depending on how much you like being grilled by your own tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addy Osmani’s agent-skills
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/addyosmani/agent-skills" rel="noopener noreferrer"&gt;Addy Osmani’s set&lt;/a&gt; is 25 “production-grade engineering skills” covering a full lifecycle: DEFINE, PLAN, BUILD, VERIFY, REVIEW, SHIP. Install with &lt;code&gt;npx skills add addyosmani/agent-skills&lt;/code&gt;. It supports Claude Code, Codex, Gemini, Copilot, Kiro, Antigravity, OpenCode, Windsurf, and Cursor. Nine slash commands: /spec, /plan, /build, /test, /constraints, /review, /webperf, /code-simplify, /ship.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/build auto&lt;/code&gt; generates the plan and implements every task after one plan approval, each task TDD’d and committed, pausing on failures or risky steps. And it is the only one here with a dedicated security-and-hardening skill. It is modular, so you can take three skills and leave the rest, and it uses progressive disclosure to keep token usage down. Light on research, UX, and prototyping. Fit: tiny to mid, and probably the best general-purpose base in the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lightweights: OpenSpec and the Catalogs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  OpenSpec
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Fission-AI/OpenSpec" rel="noopener noreferrer"&gt;OpenSpec&lt;/a&gt; is the least ceremony per change in the field. &lt;code&gt;npm i -g @fission-ai/openspec&lt;/code&gt;, &lt;code&gt;openspec init&lt;/code&gt;, needs Node 20.19 or newer. Its pitch: fluid not rigid, iterative not waterfall, built for brownfield. &lt;code&gt;/opsx:propose&lt;/code&gt; creates a change folder with proposal.md, specs/, design.md, and tasks.md. &lt;code&gt;/opsx:apply&lt;/code&gt; implements it. &lt;code&gt;/opsx:archive&lt;/code&gt; merges the delta specs into the living specs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuhzzw5shj465n1wmk4i8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuhzzw5shj465n1wmk4i8.png" alt="OpenSpec flow: /opsx:propose creates a change folder with proposal, delta specs, design and tasks, /opsx:apply implements it, and /opsx:archive merges the deltas into the living specs" width="799" height="370"&gt;&lt;/a&gt;The delta spec idea is good: requirements are written as ADDED or MODIFIED with WHEN/THEN scenarios, and the archive step means your specs stay current instead of rotting in a Google Doc. No research, PRD, UX, TDD, review, security, or unattended orchestration. It is a pure planning layer and it knows it. In the Uvik benchmark it merged 42 of 50 tickets against 36 for the control (merged, not necessarily correct). Tiny feature to large brownfield.&lt;/p&gt;

&lt;h3&gt;
  
  
  The catalogs
&lt;/h3&gt;

&lt;p&gt;Two things get recommended that are not frameworks. &lt;a href="https://github.com/github/awesome-copilot" rel="noopener noreferrer"&gt;Awesome Copilot&lt;/a&gt; is GitHub’s community catalog: 222 agents, 192 instructions, 442 skills, 107 plugins by directory count. &lt;a href="https://awesomeclaude.ai/awesome-claude-skills" rel="noopener noreferrer"&gt;Awesome Claude Skills&lt;/a&gt; is a curated directory of 241 skills in 15 categories. Both are discovery layers. You assemble your own stack out of them, and Awesome Copilot’s README warns you to inspect anything before installing, because it is third-party content. Useful. Not an answer. (If individual skills are the new part here, I wrote &lt;a href="https://dev.to/the-agent-skills-guide-i-wish-id-had/"&gt;the guide I wish I’d had&lt;/a&gt;.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ones Research Found
&lt;/h2&gt;

&lt;p&gt;The research dragged in sixteen more. The ones worth knowing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg8ay0n6gzzsu72sofmci.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg8ay0n6gzzsu72sofmci.jpg" alt="The Ones You Haven't Heard Of" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/garrytan/gstack" rel="noopener noreferrer"&gt;gstack&lt;/a&gt;&lt;/strong&gt; is Garry Tan’s setup: 23 role-based slash commands, so your agent can do a CEO review, an eng manager pass, a design review, QA, release management. Aimed at solo founders shipping products. A human drives it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/open-gsd/gsd-core" rel="noopener noreferrer"&gt;GSD Core&lt;/a&gt;&lt;/strong&gt; comes with a warning label. The most-hyped repo in this space, &lt;a href="https://github.com/gsd-build/get-shit-done" rel="noopener noreferrer"&gt;get-shit-done&lt;/a&gt; at 64k stars, got archived and moved. (Star counts in this space are glitchy right now, so treat all of them as rough hints.) The interim &lt;a href="https://github.com/gsd-build/gsd-2" rel="noopener noreferrer"&gt;gsd-2&lt;/a&gt; is also archived. If a blog post recommends GSD, check which repo it actually means before installing anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/OthmanAdi/planning-with-files" rel="noopener noreferrer"&gt;planning-with-files&lt;/a&gt;&lt;/strong&gt; does one thing: Manus-style persistent markdown plans with session recovery after /clear and compaction, per-turn plan re-injection, and a deterministic completion gate. Works across 60-plus agents. Built for long tasks and crash recovery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ralph loops&lt;/strong&gt; are a pattern, not a product: loop an agent against a PRD until it is done. The original &lt;a href="https://github.com/snarktank/ralph" rel="noopener noreferrer"&gt;snarktank/ralph&lt;/a&gt; has been stale since February. &lt;a href="https://github.com/frankbria/ralph-claude-code" rel="noopener noreferrer"&gt;frankbria/ralph-claude-code&lt;/a&gt; is alive and adds “intelligent exit detection,” which is a feature you only need because the naive version never stops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/gotalab/cc-sdd" rel="noopener noreferrer"&gt;cc-sdd&lt;/a&gt;&lt;/strong&gt; is a minimal Kiro-style spec harness (requirements, design, tasks, implement) whose pitch is turning approved specs into long-running autonomous implementation. Tiny, but interesting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/affaan-m/ECC" rel="noopener noreferrer"&gt;ECC&lt;/a&gt;&lt;/strong&gt; (Everything Claude Code) is 285k stars of kitchen-sink harness config. It doesn’t give you a process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/ruvnet/ruflo" rel="noopener noreferrer"&gt;ruflo&lt;/a&gt;&lt;/strong&gt;, formerly claude-flow, does multi-agent swarm orchestration with memory and vector RAG. Huge star count, marketing-flavored README. Treat the claims cautiously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/eyaltoledano/claude-task-master" rel="noopener noreferrer"&gt;claude-task-master&lt;/a&gt;&lt;/strong&gt;, the classic PRD-to-tasks MCP, has not been pushed in about six months. Momentum has moved elsewhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/EveryInc/compound-engineering-plugin" rel="noopener noreferrer"&gt;Compound Engineering&lt;/a&gt;&lt;/strong&gt; is Every’s plugin (25k stars) for Claude Code, Codex, and Cursor, built around a plan, work, review, compound loop where the lessons from each cycle feed the next one. It is the sibling of the compound-writing plugin I run in this vault, and the review and research behavior lives inside its skills rather than as standalone agents. Aimed at small teams and mid-size work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/code-yeongyu/oh-my-openagent" rel="noopener noreferrer"&gt;oh-my-openagent&lt;/a&gt;&lt;/strong&gt;, formerly oh-my-opencode, is a 70k-star orchestration harness that started on opencode, with an “ultrawork” autonomous mode. It orchestrates and doesn’t plan. &lt;a href="https://dev.to/the-expensive-model-only-plans-now-i-split-my-ai-coding-rig-across-two-tools/"&gt;I use opencode&lt;/a&gt;, so I had to look.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few more deserve one line each. &lt;a href="https://dev.to/how-i-built-two-obsidian-plugins-while-kiro-ai-did-most-of-the-work/"&gt;Kiro&lt;/a&gt; is AWS’s spec-driven IDE (requirements, design, tasks, review gates), and it’s its own category because it’s a proprietary IDE, not a pack of skills you drop into your agent. &lt;a href="https://github.com/buildermethods/agent-os" rel="noopener noreferrer"&gt;Agent OS&lt;/a&gt; injects your codebase standards into specs. &lt;a href="https://github.com/gemini-cli-extensions/conductor" rel="noopener noreferrer"&gt;Conductor&lt;/a&gt; does spec, plan, implement for Claude Code and Antigravity. &lt;a href="https://github.com/maxritter/pilot-shell" rel="noopener noreferrer"&gt;pilot-shell&lt;/a&gt; (now QualityLayer) bolts TDD and quality gates onto a spec flow. &lt;a href="https://github.com/spec-kitty/spec-kitty" rel="noopener noreferrer"&gt;spec-kitty&lt;/a&gt; is Spec Kit with a governance charter. All smaller, all alive, none changed my picks. The list grows faster than I can install them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Size Chart
&lt;/h2&gt;

&lt;p&gt;Here is the point of the post, the mapping the research synthesis landed on:&lt;/p&gt;

&lt;p&gt;The evidence base up front: one big success of mine, one solo failure, a vendor benchmark, and a subagent’s read of the repos and the web, not twenty-five installs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tiny script or one-file fix:&lt;/strong&gt; none of them. BMAD’s own docs and Superpowers’ critics agree on this. Skip process, or at most grab a single skill, like Pocock’s tdd or one of Addy’s.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small backend/API:&lt;/strong&gt; OpenSpec, or Addy /spec + /build, or Superpowers, or Pocock’s grill + tdd.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mid app:&lt;/strong&gt; Superpowers, Addy’s full lifecycle, Pocock to-spec/to-tickets, or Spec Kit. BMAD if you actually want the PRD and UX docs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large multi-feature:&lt;/strong&gt; BMAD plus the Loop add-on, Spec Kit with a constitution, Pocock wayfinder + implement-spec, or PStack orchestrate. OpenSpec Stores (beta) if the problem spans repos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the coverage reality check, because stars and READMEs lie by omission: only BMAD covers the full span from research to retro. Only Addy ships a dedicated security skill, as far as I could find. Only Superpowers makes TDD mandatory. Only PStack will orchestrate a multi-day PR stack. OpenSpec covers planning and nothing else.&lt;/p&gt;

&lt;p&gt;Y means a dedicated skill or phase, p is partial, and a dash is nothing. Most cells come from reading the repos and docs. A few are inferred from skill lists, because reading every SKILL.md in every repo is a job, not a blog post, so treat the dashes as “I didn’t find it,” not “it can’t.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6yflde0r3fzqx7e8vz1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6yflde0r3fzqx7e8vz1h.png" alt="Size ladder matching planning ceremony to project size: no framework for tiny fixes, OpenSpec or Addy for small APIs, Superpowers or Spec Kit for mid apps, BMAD plus Loop or PStack for large multi-feature work" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Addy&lt;/th&gt;
&lt;th&gt;PStack&lt;/th&gt;
&lt;th&gt;Pocock&lt;/th&gt;
&lt;th&gt;BMAD&lt;/th&gt;
&lt;th&gt;Superpowers&lt;/th&gt;
&lt;th&gt;Spec Kit&lt;/th&gt;
&lt;th&gt;OpenSpec&lt;/th&gt;
&lt;th&gt;Compound Eng.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Research&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;p (opt-in)&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brief / PRD&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Design / UX&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prototyping&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TDD / testing&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unattended long run&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And since the first thing I wanted to know was whether anything besides BMAD has a real research component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BMAD&lt;/strong&gt; (&lt;code&gt;bmad-deep-recon&lt;/code&gt;): the only one that does real multi-source research. It covers market, domain, technical, competitive, and user-voice research, can run parallel web searches itself, and writes a cited research.md.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pocock&lt;/strong&gt; (&lt;code&gt;research&lt;/code&gt;): the runner-up. A background agent investigates a question from primary sources (docs, source, specs, first-party APIs) and writes it up as a Markdown file with citations. Real research, just small.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Addy&lt;/strong&gt; (&lt;code&gt;source-driven-development&lt;/code&gt;): not open-ended research. It makes the agent follow the official docs for the versions you actually run and cite each decision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PStack&lt;/strong&gt; (investigation playbook): read-only “how and why” digging in your own codebase. That’s code investigation; it never leaves your repo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spec Kit&lt;/strong&gt; (opt-in assess extension): gathers evidence on users, market, and prior art for a go or kill call. I couldn’t verify how deep it goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenSpec&lt;/strong&gt; (&lt;code&gt;/opsx:explore&lt;/code&gt;): a thinking partner that reads your code and compares options. Not research.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Superpowers&lt;/strong&gt; : nothing. Brainstorming is the closest it gets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security is the other lopsided column. Addy’s security-and-hardening skill threat-models and walks a hardening checklist, but it is guidance, not a scanner. Everything else in the table either has no security lens or I couldn’t confirm one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gap: Nobody Built the API-Only One
&lt;/h2&gt;

&lt;p&gt;Now the finding I ran the research for. Most of my small projects are backend-only APIs, so I had the research ask a question: is there a lightweight framework for API and backend projects? One that skips the UI phases and leans on contract design, security, and API design instead?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3svvm8ojtxmvjhgqt47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg3svvm8ojtxmvjhgqt47.png" alt="Eight-phase API-only planning pipeline from brief.md through data-model, openapi.yaml contract, security, architecture, test-plan and ops to tasks.md, with a verify pass checking every endpoint has authz, tests and tasks" width="799" height="373"&gt;&lt;/a&gt;The verdict is a gap. Nothing bundles OpenAPI-first contract design, threat modeling against the &lt;a href="https://owasp.org/API-Security/" rel="noopener noreferrer"&gt;OWASP API Top 10&lt;/a&gt;, data modeling, and test planning into a spec pipeline an unattended agent can execute.&lt;/p&gt;

&lt;p&gt;The pieces exist, scattered across repos. &lt;a href="https://github.com/wshobson/agents" rel="noopener noreferrer"&gt;wshobson/agents&lt;/a&gt; has the closest components: a backend-development plugin, api-scaffolding, backend-api-security agents, and a security-scanning plugin with STRIDE analysis and attack-tree skills. There is a tiny threat-model skill (&lt;a href="https://github.com/alpha-omega-security/threat-model" rel="noopener noreferrer"&gt;alpha-omega-security&lt;/a&gt;, 59 stars) and an OWASP Top 10 skill (&lt;a href="https://github.com/agamm/claude-code-owasp" rel="noopener noreferrer"&gt;agamm/claude-code-owasp&lt;/a&gt;, 388 stars), though that one targets the web Top 10, not the API Top 10. Addy’s set has api-and-interface-design and security-and-hardening, and nothing forces you to install the frontend skill. There are contract-first OpenAPI skills floating around the directories. Nobody glued any of it into a pipeline.&lt;/p&gt;

&lt;p&gt;The research even sketched the glue. Eight short phases, each emitting one artifact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;brief.md:&lt;/strong&gt; scope, auth model, SLOs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;data-model.md:&lt;/strong&gt; entities, PII classification, migrations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;openapi.yaml:&lt;/strong&gt; resources, error model, idempotency, versioning, linted as a gate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;security.md:&lt;/strong&gt; STRIDE per endpoint, an authz matrix, OWASP API checklist mapped to testable requirements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;architecture.md:&lt;/strong&gt; one-page ADRs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;test-plan.md:&lt;/strong&gt; contract tests generated from the OpenAPI spec, authz negative tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ops.md:&lt;/strong&gt; logs, metrics, runbook stub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tasks.md:&lt;/strong&gt; vertical slices with acceptance criteria pointing back at the contract and the security rows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus a verify skill that cross-checks the plan: every endpoint has an authz row, tests, and tasks.&lt;/p&gt;

&lt;p&gt;And yes, an eight-artifact pipeline for small APIs sounds like hiring the general contractor to hang the picture frame. The axis that justifies it is not project size, it is unattended time: an agent running alone for days needs the contract and the security rows written down whether the app is big or small.&lt;/p&gt;

&lt;p&gt;The cheapest path is composing Addy’s lifecycle with wshobson’s security pieces and an OpenAPI contract skill, then writing only the glue. Which sounds like the kind of thing I will build at 11 PM some night and then have to write another blog post about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’m Doing With This
&lt;/h2&gt;

&lt;p&gt;The mapping for my own pile: big apps get BMAD, because the last one proved the ceremony pays for itself at that size. Small APIs get OpenSpec or Addy’s /spec + /build until someone builds the API gap pack. Mid-size is the hard call, and right now I would pick Pocock’s grill-first flow or Superpowers, depending on how much I trust myself not to skip tests.&lt;/p&gt;

&lt;p&gt;Two caveats before you take any of this as gospel. Everything above traces to a research pass run on 2026-10-16. Stars and push dates come from the GitHub API, the matrix is part inference, and the criticisms are web-reported. And this space mutates monthly. GSD got archived while I was writing this post. Check the repos before you commit to anything.&lt;/p&gt;

&lt;p&gt;And the meta point, because it is the actual plan: the research for this post ran unattended, a subagent doing the reading while I did other things. Get every project planned well enough that an agent can execute it without me, then feed the machine. The API gap pack might be the first thing I plan that way. Or it becomes project number sixteen.&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>skills</category>
    </item>
    <item>
      <title>Two Files and a Skill: How I Plan AI Coding Projects Without a Framework</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Wed, 28 Oct 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/two-files-and-a-skill-how-i-plan-ai-coding-projects-without-a-framework-55nl</link>
      <guid>https://dev.to/eristoddle/two-files-and-a-skill-how-i-plan-ai-coding-projects-without-a-framework-55nl</guid>
      <description>&lt;p&gt;This is finally the breakdown I promised at the end of &lt;a href="https://dev.to/eristoddle/multiple-choice-is-not-a-decision-teaching-a-planning-agent-to-ask-more-questions-4bd2"&gt;the last post&lt;/a&gt;: how the &lt;code&gt;living plan&lt;/code&gt; skill works, start to finish, so you don’t have to read through the repo to figure it out.&lt;/p&gt;

&lt;p&gt;You can find it in &lt;a href="https://github.com/eristoddle/agent-skills" rel="noopener noreferrer"&gt;my agent-skills repo&lt;/a&gt;, it’s 13 files and about a thousand lines, and it runs in five of my projects. The six posts before this one were each a complaint. I realized that’s not the best way to learn about a tool, so this post covers how it works.&lt;/p&gt;

&lt;p&gt;A project that runs for months needs a place to keep decisions, a place where work items get created, and something that keeps both of those from loading up with unimportant or archivable information.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the Skill Adds to a Project&lt;/li&gt;
&lt;li&gt;Where It Sits Next to BMAD, Spec Kit, and the Rest&lt;/li&gt;
&lt;li&gt;The Router: Five States, Five Workflows&lt;/li&gt;
&lt;li&gt;Grill: The Workflow That Makes Things&lt;/li&gt;
&lt;li&gt;Scaffold: Plumbing After Design&lt;/li&gt;
&lt;li&gt;
Adopt: Retrofit Existing Projects

&lt;ul&gt;
&lt;li&gt;Naming variance is a feature&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Why Questions Are Pointers&lt;/li&gt;
&lt;li&gt;The Threshold, and What Counts as Cooled&lt;/li&gt;
&lt;li&gt;The Ledger: How the Judgment Turns Into Rules&lt;/li&gt;
&lt;li&gt;Evict-Tasks: Check, Collapse, Evict&lt;/li&gt;
&lt;li&gt;
The Implementer: First Agent, and So Far the Only One

&lt;ul&gt;
&lt;li&gt;The model line that wasn’t there&lt;/li&gt;
&lt;li&gt;What the first real run taught it&lt;/li&gt;
&lt;li&gt;What comes next for agents&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Rules Under Everything&lt;/li&gt;
&lt;li&gt;Where This Leaves It&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the Skill Adds to a Project
&lt;/h2&gt;

&lt;p&gt;There are four moving parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PLAN.md&lt;/code&gt;&lt;/strong&gt; is the active layer. It’s the decision record, the open questions, the parking lot, and a short session log. The planning agent reads it every session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;TASKS.md&lt;/code&gt;&lt;/strong&gt; is the handoff document. When a decision is concrete enough to build, the planning thread writes it up here as a list of tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;implementer&lt;/code&gt; agent&lt;/strong&gt; executes that queue &lt;a href="https://dev.to/eristoddle/the-subagents-guide-i-wish-id-had-dhh"&gt;in its own context window&lt;/a&gt;, on a cheaper model, while the planning thread keeps working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;docs/&lt;/code&gt; tree&lt;/strong&gt; is the inactive layer. Old sessions, cooled decisions, and the full discussion behind every open question live here, one file per item, behind a one-line pointer in &lt;code&gt;PLAN.md&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The skill owns the process. A project gets a one-line pointer in its &lt;code&gt;CLAUDE.md&lt;/code&gt; that says to invoke &lt;code&gt;living-plan&lt;/code&gt;, and that’s it. The heavy logic stays in the skill’s &lt;code&gt;workflows/&lt;/code&gt; and &lt;code&gt;references/&lt;/code&gt; folders and &lt;a href="https://dev.to/eristoddle/the-agent-skills-guide-i-wish-id-had-17i1"&gt;loads when needed&lt;/a&gt;, one file for whichever path you’re on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx94kd0ridur55xoux3u7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx94kd0ridur55xoux3u7.png" alt="How the living-plan pieces connect: CLAUDE.md points at the skill, PLAN.md hands decisions to TASKS.md, the implementer agent works the queue, and docs/ holds the inactive layer behind one-line pointers" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It Sits Next to BMAD, Spec Kit, and the Rest
&lt;/h2&gt;

&lt;p&gt;I’ve been reading through the bigger agent frameworks lately and using some of them: BMAD, Spec Kit, Superpowers, OpenSpec, Matt Pocock’s skills, and mine fits underneath all of them, weight-wise. It’s lightweight as hell, and that was kind of the goal. I wasn’t trying to reinvent the wheel.&lt;/p&gt;

&lt;p&gt;There’s no PRD, no UX phase, no architecture doc template, no story files, and no agile stuff. BMAD will take you from product brief to retrospective, and on a big app it’s worth it. I am building another project using BMAD right now and loving it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59m514vqc19dwi5wcvgf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59m514vqc19dwi5wcvgf.jpg" alt="Where It Sits Next to BMAD, Spec Kit, and the Rest" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What my skill does is much smaller. It keeps a planning doc and a task file as lean as possible while you plan and build in small loops, which is how I work on a lot of my side projects. They are explorations that become something eventually. I find what that is by building, so I needed something that holds a trail of where I’ve been, not something that wants the thinking done upfront.&lt;/p&gt;

&lt;p&gt;It also isn’t original, and that’s fine. It uses some of the same ideas the bigger frameworks do. The &lt;code&gt;docs/&lt;/code&gt; tree that keeps the plan current while old material moves out is the same instinct as OpenSpec archiving its change specs into living specs. The decision record is what every spec-driven tool creates. And the interview at the front of it, the grill, I took straight from Matt Pocock and said so &lt;a href="https://dev.to/eristoddle/multiple-choice-is-not-a-decision-teaching-a-planning-agent-to-ask-more-questions-4bd2"&gt;in the last post&lt;/a&gt;. I put the pieces together to keep it small enough that planning and task work can stay iterative without a framework owning everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Router: Five States, Five Workflows
&lt;/h2&gt;

&lt;p&gt;The skill starts with a detection step. It looks around before it does anything and discovers which files exist and what their jobs are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# planning doc&lt;/span&gt;
&lt;span class="nb"&gt;ls &lt;/span&gt;PLAN.md PLAN.MD plan.md 2&amp;gt;/dev/null
&lt;span class="c"&gt;# task handoff (tolerate singular/plural)&lt;/span&gt;
&lt;span class="nb"&gt;ls &lt;/span&gt;TASK.md TASKS.md 2&amp;gt;/dev/null
&lt;span class="c"&gt;# conductor: CLAUDE.md is often a SYMLINK to AGENTS.md or vice versa&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; CLAUDE.md AGENTS.md 2&amp;gt;/dev/null
&lt;span class="c"&gt;# already rebalanced?&lt;/span&gt;
&lt;span class="nb"&gt;ls &lt;/span&gt;docs/decisions docs/sessions docs/questions docs/parking-lot 2&amp;gt;/dev/null
&lt;span class="c"&gt;# size proxy, for BOTH docs&lt;/span&gt;
&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; PLAN.md TASKS.md 2&amp;gt;/dev/null
&lt;span class="c"&gt;# how much of the task doc is already finished?&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'^\s*-\s*\[x\]'&lt;/span&gt; TASKS.md 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'^\s*-\s*\[\]'&lt;/span&gt; TASKS.md 2&amp;gt;/dev/null

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it classifies the project and routes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Detected by&lt;/th&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Greenfield&lt;/td&gt;
&lt;td&gt;no planning doc present&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;grill&lt;/code&gt;, then &lt;code&gt;scaffold&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;planning doc exists, but no task file, no implementer agent, or no &lt;code&gt;docs/&lt;/code&gt; tree&lt;/td&gt;
&lt;td&gt;&lt;code&gt;adopt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mature&lt;/td&gt;
&lt;td&gt;full system present, planning doc heavy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rebalance&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task doc bloated&lt;/td&gt;
&lt;td&gt;task doc heavy and mostly finished work&lt;/td&gt;
&lt;td&gt;&lt;code&gt;evict-tasks&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deciding, not filing&lt;/td&gt;
&lt;td&gt;not a filesystem state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;grill&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Four rows cover things you can see in the directory. The last one triggers on what you are doing at the time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PLAN.md&lt;/code&gt; and &lt;code&gt;TASKS.md&lt;/code&gt; both load up with content, but for different reasons. A planning doc bloats because decisions pile up. A task doc bloats because finished tasks never leave the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grill: The Workflow That Makes Things
&lt;/h2&gt;

&lt;p&gt;I covered this one in &lt;a href="https://dev.to/eristoddle/multiple-choice-is-not-a-decision-teaching-a-planning-agent-to-ask-more-questions-4bd2"&gt;the last post&lt;/a&gt; and stole the idea for it from &lt;a href="https://www.aihero.dev/skills-grill-me" rel="noopener noreferrer"&gt;Matt Pocock&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Four of the five workflows modify existing files. Grill is the only one that creates new things. It interviews me and puts the results under one of four headings: decided, open question, parked, or not applicable.&lt;/p&gt;

&lt;p&gt;Ideas usually follow a specific path: parking lot, then open question, then decision, then task queue. Grill moves an item and asks before it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaffold: Plumbing After Design
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffqfcapfsmoe98dqecb65.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffqfcapfsmoe98dqecb65.jpg" alt="Scaffold: Plumbing After Design" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On a brand new project, grill runs first and scaffold runs second. That order is a fix. Scaffold used to open with “what is this project?” and then emit a &lt;code&gt;PLAN.md&lt;/code&gt; with an empty decisions section.&lt;/p&gt;

&lt;p&gt;Scaffold’s interview is all about plumbing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What the docs are called. Default is &lt;code&gt;PLAN.md&lt;/code&gt;, &lt;code&gt;TASKS.md&lt;/code&gt;, and &lt;code&gt;CLAUDE.md&lt;/code&gt;, with &lt;code&gt;TASK.md&lt;/code&gt; and &lt;code&gt;AGENTS.md&lt;/code&gt; offered if the repo already has those files.&lt;/li&gt;
&lt;li&gt;Whether to create the implementer agent, and which model it runs on. Default is Sonnet.&lt;/li&gt;
&lt;li&gt;Whether there’s a copy of the task list somewhere outside the repo, like a note in a notes app. If there is, the conductor gets one line saying where it is and when to reconcile it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If I skip the grill or bail halfway, scaffold still runs on whatever got decided.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adopt: Retrofit Existing Projects
&lt;/h2&gt;

&lt;p&gt;Most of my projects didn’t start with this skill. They had their own docs and their own idiosyncrasies, and the skill had to go into them without breaking anything.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;adopt&lt;/code&gt; diffs the project against the full system and adds only what’s missing. It touches existing docs only to add pointers.&lt;/p&gt;

&lt;p&gt;The best example I have is a project called sychysis. When I surveyed my projects for this series, an earlier pass recorded it as having “no PLAN.md at all” and filed it as a project without the system. That was wrong. It’s fully in the system. It just doesn’t look like the template. Here’s the config block at the top of its ledger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Config&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**planning doc:**&lt;/span&gt; &lt;span class="sb"&gt;`docs/vision.md`&lt;/span&gt; (was &lt;span class="sb"&gt;`docs/rough-plan.md`&lt;/span&gt;)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**task doc:**&lt;/span&gt; &lt;span class="sb"&gt;`TASKS.md`&lt;/span&gt; (repo root)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**conductor:**&lt;/span&gt; &lt;span class="sb"&gt;`AGENTS.md`&lt;/span&gt; (no &lt;span class="sb"&gt;`CLAUDE.md`&lt;/span&gt;; not a symlink)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**archive:**&lt;/span&gt; &lt;span class="sb"&gt;`docs/archive/`&lt;/span&gt; (completed batches, frozen)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**threshold:**&lt;/span&gt; 15000 words (default)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**executor:**&lt;/span&gt; opencode (see &lt;span class="sb"&gt;`opencode.json`&lt;/span&gt;); &lt;span class="gs"&gt;**planner:**&lt;/span&gt; Claude Code

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The planning doc isn’t called &lt;code&gt;PLAN.md&lt;/code&gt;. There’s no &lt;code&gt;CLAUDE.md&lt;/code&gt;. It runs two tools, Claude Code planning and opencode executing, which is &lt;a href="https://dev.to/eristoddle/the-expensive-model-only-plans-now-i-split-my-ai-coding-rig-across-two-tools-4dch"&gt;the split from post four&lt;/a&gt;. And it already had a &lt;code&gt;docs/decisions/&lt;/code&gt; folder full of ADRs before the skill ever showed up. The ledger says that those ADRs belong to the project and must not be confused with the skill’s decisions.&lt;/p&gt;

&lt;p&gt;None of that is drift. It’s the skill bending around a project that was there first, with the details written down so the next run doesn’t have to find them next time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Naming variance is a feature
&lt;/h3&gt;

&lt;p&gt;Half the fragility in tools like this comes from assuming file names. So the skill tolerates &lt;code&gt;TASK.md&lt;/code&gt; and &lt;code&gt;TASKS.md&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt; and &lt;code&gt;CLAUDE.md&lt;/code&gt;, and records whatever it finds in the ledger once.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd4ahdgt16my0cchpoii5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd4ahdgt16my0cchpoii5.jpg" alt="Naming variance is a feature" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; is very often a symlink to &lt;code&gt;AGENTS.md&lt;/code&gt;. Anything that edits “the conductor” has to resolve the link and edit the real file. Write through the link with the wrong tool and some of them will replace the symlink with a regular file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Questions Are Pointers
&lt;/h2&gt;

&lt;p&gt;Things in &lt;code&gt;PLAN.md&lt;/code&gt; get one of two treatments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decisions stay whole and inline while they’re active.&lt;/strong&gt; A decision is a &lt;code&gt;Dxx&lt;/code&gt; record in the decisions section, body and all, because it’s load-bearing and the planning agent needs the reasoning every session. When it cools down, it collapses to a one-line heading plus a link, and the body moves to &lt;code&gt;docs/decisions/Dxx.md&lt;/code&gt;. The ID never changes, so anything that referred to D14 still resolves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open questions and parking-lot items are born as pointers.&lt;/strong&gt; From the moment one exists, &lt;code&gt;PLAN.md&lt;/code&gt; shows only the one-line heading and a link to &lt;code&gt;docs/questions/Qxx.md&lt;/code&gt; or &lt;code&gt;docs/parking-lot/Pxx.md&lt;/code&gt;. The discussion lives in the file.&lt;/p&gt;

&lt;p&gt;Questions grow and decisions don’t. A decision is a conclusion. Once it’s made it mostly sits there. A question is an argument still in progress. Every grill round that touches it appends a new dated section, because the sequence of what I thought in June is what makes the July answer make sense. Put that inline and an open question gets read every session, for months, mostly to rediscover that I still don’t know.&lt;/p&gt;

&lt;p&gt;And questions are deferred by nature. The planning agent needs to know the question exists. It doesn’t need the whole history until somebody’s ready to answer it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6l74i23e77subqgaqwyd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6l74i23e77subqgaqwyd.png" alt="Where items live: a decision stays whole in PLAN.md while hot, then cools to a one-line pointer with its body in docs/decisions, while questions and parking-lot items are pointers from the start" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two markers on decision headings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🔒 foundational&lt;/strong&gt; means it never cools, even if nothing points at it. Some decisions are load-bearing for work that hasn’t started yet, like an architectural split a future feature depends on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔨 unbuilt&lt;/strong&gt; means the decision is cold enough to archive, but the work it describes hasn’t shipped. The marker survives on the pointer line, so the decisions index doubles as a list of things I decided to build and haven’t.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Threshold, and What Counts as Cooled
&lt;/h2&gt;

&lt;p&gt;The skill’s default threshold is 15,000 words for the planning doc and it’s just a nudge. If I invoke the skill and &lt;code&gt;PLAN.md&lt;/code&gt; is over, it says so: “PLAN.md is 27.6k words, about 12k over threshold, want to rebalance?” The real entry point is me asking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F12bol6bh2n8fpl75git0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F12bol6bh2n8fpl75git0.jpg" alt="The Threshold, and What Counts as Cooled" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The word count is a stand-in for what I actually care about, which is &lt;a href="https://dev.to/eristoddle/planning-is-cheaper-than-coding-and-my-own-logs-proved-me-wrong-about-why-51bh"&gt;how much context every session burns&lt;/a&gt; reading the plan. The agent can’t reliably read its own context usage. It can run &lt;code&gt;wc -w&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the task doc the nudge is a ratio, not a size. When finished work is over about 60% of the file, it says that, in numbers.&lt;/p&gt;

&lt;p&gt;What gets moved during a rebalance depends on what kind of thing it is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Session log entries&lt;/strong&gt; go by recency. Keep the last three inline, archive the rest. No judgment needed, and this is usually where most of the weight is, so it goes first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decisions&lt;/strong&gt; go by reference, not age. A decision cools when nothing currently active points at it (no open question, no parking-lot item, not the live task, not a recent session) and it isn’t flagged foundational.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Questions and parking-lot items&lt;/strong&gt; were never inline to begin with, so there’s nothing to move.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s where my five projects stand today:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Planning doc&lt;/th&gt;
&lt;th&gt;Words&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;writing-model-research&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PLAN.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;17,324&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nsf-scifi-wiki&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PLAN.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10,876&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deep-research-agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PLAN.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10,395&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;content-tools-v2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PLAN.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8,588&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sychysis&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docs/vision.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8,313&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;content-tools-v2 is the project I confessed about twice in this series. It was at 16,939 words in August. It’s at about half that now.&lt;/p&gt;

&lt;p&gt;The one over the line is writing-model-research, and it’s the most interesting number in the table. In August it had a planning doc of about 1,500 words. It’s also the project the grill has run in most. Grilling generates decisions, decisions are most of a mature planning doc. That’s the loop working. It just means that project is due a rebalance, and I haven’t run it yet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx2sqtimtdyp9vtaffy6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx2sqtimtdyp9vtaffy6u.png" alt="Bar chart of planning doc word counts across five projects, with writing-model-research at 17,324 words the only one past the 15,000-word threshold" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ledger: How the Judgment Turns Into Rules
&lt;/h2&gt;

&lt;p&gt;Every project gets a small append-only file at &lt;code&gt;docs/rebalance-log.md&lt;/code&gt;. It does three jobs.&lt;/p&gt;

&lt;p&gt;It’s the &lt;strong&gt;audit trail&lt;/strong&gt;. Every relocation gets one line with a reason, so every move can be traced back and reverted.&lt;/p&gt;

&lt;p&gt;It’s the &lt;strong&gt;per-project config&lt;/strong&gt;. Which file is the planning doc, which is the task doc, which is the conductor, what the threshold is, and what deviates from the standard shape. That’s what lets sychysis look nothing like the template without the skill guessing from scratch every run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjif93twj619lvoughu6q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjif93twj619lvoughu6q.jpg" alt="The Ledger: How the Judgment Turns Into Rules" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it’s the &lt;strong&gt;seed for automation&lt;/strong&gt;. Early on, every hot-or-cold call is made by hand and logged with its reason. After each run, the skill scans the ledger for a reason that has shown up in three or more runs and isn’t a rule yet, and pitches exactly one: “You’ve cooled superseded decisions four runs straight. Make that automatic?” If I say yes, it moves into a &lt;code&gt;Rules&lt;/code&gt; section and runs mechanically from then on.&lt;/p&gt;

&lt;p&gt;I didn’t design the rules up front, because I’d have gotten them wrong. They get mined from what I actually do. Even then, nothing stops being propose-then-confirm. Automation just shrinks how much I have to remember and look at manually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82xidsvb9yjd9va22du7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F82xidsvb9yjd9va22du7.png" alt="Flowchart of the ledger loop: hand calls are logged with a reason, a reason seen in three or more runs gets pitched as one rule, and a confirmed rule moves into the Rules section" width="799" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;sychysis’s ledger shows what this turns into. It has rules like “the executor may append to the parking lot; only the planner may promote out of it,” and “never reference a living doc by line number.” That last one came from a specific mistake and is now written down where the next run will read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evict-Tasks: Check, Collapse, Evict
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/eristoddle/the-other-doc-got-fat-too-my-task-file-was-90-finished-work-4hjc"&gt;Post five&lt;/a&gt; is the story of this one. The task doc already had a collapse rule: finished queues shrink to a one-block summary with a &lt;code&gt;[tag]&lt;/code&gt;. It didn’t have a step where those summaries actually leave. Check, collapse, and then nothing. The third stage was missing.&lt;/p&gt;

&lt;p&gt;A collapsed block gets evicted when every piece in it is checked and nothing still open references it. That second condition is a judgment call, which is why eviction never happens automatically at the end of a queue. The implementer especially must not do it, because it would be editing the file that holds its own run state while it runs.&lt;/p&gt;

&lt;p&gt;Before anything moves, two kinds of material get lifted out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lessons.&lt;/strong&gt; Gotchas and landmines the next similar job will need. If the next person doing this kind of pass would want it, it’s a lesson, not history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The inventory.&lt;/strong&gt; If the done blocks are the only record of which scripts exist, that table belongs in the code’s README.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Everything else moves verbatim, by line range with &lt;code&gt;sed&lt;/code&gt;, never retyped. Retyping a 700-line block is how detail disappears.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fksp70g9tcx3imaqqzjyd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fksp70g9tcx3imaqqzjyd.png" alt="Evict-tasks flow: check, collapse into a tagged summary, confirm nothing open references it, lift out lessons and inventory, then evict verbatim with sed into the archive" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Implementer: First Agent, and So Far the Only One
&lt;/h2&gt;

&lt;p&gt;Every task in &lt;code&gt;TASKS.md&lt;/code&gt; has the same sections: goal, why (as a pointer back to the decision), a run-state note, the numbered pieces, files, tests, what’s out of scope, and what to report back. The agent is cold on the planning conversation but warm on the project. It has the codebase and the conductor, so it doesn’t need the repo explained. It needs the job specified.&lt;/p&gt;

&lt;p&gt;The agent template is short and the rules are blunt:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2gadexnkba5op3afwkeq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2gadexnkba5op3afwkeq.jpg" alt="The Implementer: First Agent, and So Far the Only One" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work the numbered pieces as a serial queue, top to bottom, one pass. &lt;a href="https://dev.to/eristoddle/the-bottleneck-was-me-how-i-stopped-racing-my-ai-builder-and-started-pacing-it-3e1n"&gt;Serial is on purpose&lt;/a&gt;. The point is pacing, not throughput.&lt;/li&gt;
&lt;li&gt;A blocked piece doesn’t stop the queue. Mark it &lt;code&gt;[!]&lt;/code&gt; with a one-line reason and keep going with anything that doesn’t depend on it.&lt;/li&gt;
&lt;li&gt;Update the run-state note on every stop, done or blocked. If the session dies, the task file is the recovery point.&lt;/li&gt;
&lt;li&gt;No design decisions. Ever. A fork the spec doesn’t cover gets escalated, not guessed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That queue serves two rhythms. Stack a few pieces and plan the next batch while the agent grinds, or stack a lot and walk away.&lt;/p&gt;

&lt;h3&gt;
  
  
  The model line that wasn’t there
&lt;/h3&gt;

&lt;p&gt;Here’s a mistake that lived in this skill for a while. The implementer template has a &lt;code&gt;model:&lt;/code&gt; line, and scaffold’s interview even asks which model to use. But neither scaffold nor adopt listed `` among the placeholders to fill. The placeholder was orphaned.&lt;/p&gt;

&lt;p&gt;So when the agent got backfilled into writing-model-research, the unfilled line got deleted instead of filled in. A Claude Code agent with no &lt;code&gt;model:&lt;/code&gt; line inherits the model of the session that launches it. Mine was Opus. The whole point of the implementer is to run the grind on something cheaper, and I’d accidentally built a cheap-looking wrapper that ran on the most expensive model I have.&lt;/p&gt;

&lt;p&gt;Both workflows now list every placeholder explicitly, and adopt checks existing agents for a missing &lt;code&gt;model:&lt;/code&gt; line even when the agent folder looks complete. The rule that came out of it is in the skill in plain words: a missing &lt;code&gt;model:&lt;/code&gt; line is worse than an unfilled one. An unfilled one is visibly broken. A missing one is invisibly expensive.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the first real run taught it
&lt;/h3&gt;

&lt;p&gt;The first serious queue through the implementer in that project was a diagnostic job: 29 of 80 extracted novels were coming out of a text-prep script with zero scene breaks detected. In that project the implementer wraps a cheaper model and hands the reading and grinding to pi, a command line coding tool running DeepSeek, which is a whole other post.&lt;/p&gt;

&lt;p&gt;The cheap route did better than I expected. It found the real cause, shipped a fairly subtle fix, recovered 9 of the 29 books, and correctly refused two design forks instead of guessing. That’s the contract working exactly as written.&lt;/p&gt;

&lt;p&gt;Then it reported that word counts were “verified unchanged across all 80 books.” They weren’t. When I sent it back, the real problem was worse than a bad number. It had compared a dry run of the old script against a dry run of the new one. Internally consistent. The verification was measuring itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fftz07jcwywb23f1fpkv9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fftz07jcwywb23f1fpkv9.jpg" alt="What the first real run taught it" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And to be fair to the agent, I got the follow-up wrong too. My alarm about lost content traced back to a stale baseline from an older script version, not to the patch. But raising it turned up a real bug anyway and forced the check to be redone properly.&lt;/p&gt;

&lt;p&gt;The lesson isn’t “use a smarter model.” A smarter model makes the same methodology error. The lesson is that verification has to be against disk, not against another run of yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  What comes next for agents
&lt;/h3&gt;

&lt;p&gt;The implementer is a generic worker. The skill has a catalog of agents it knows how to backfill, and right now it has one entry. Adding another type means dropping a template into &lt;code&gt;templates/agents/&lt;/code&gt; and registering its name, and every project can then adopt it through the same workflow. I may add agents that do something other than implement. I haven’t yet, and I’m not going to pretend there’s a roadmap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rules Under Everything
&lt;/h2&gt;

&lt;p&gt;These are the parts that would survive a rewrite.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Propose, then confirm.&lt;/strong&gt; Every action that changes a file shows a manifest first. Nothing gets overwritten or relocated on the skill’s own say-so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never lossy.&lt;/strong&gt; Things move, they don’t get deleted. Thread files append, they don’t get rewritten.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The planner stays light.&lt;/strong&gt; Heavy process lives in the skill and loads only when needed. The project gets pointers, never copies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure what you can control.&lt;/strong&gt; The agent can’t read its own context usage. It can count words.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the deviations down.&lt;/strong&gt; A project that doesn’t fit the template is fine. A project that doesn’t fit and doesn’t say how is a puzzle for the next session.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where This Leaves It
&lt;/h2&gt;

&lt;p&gt;Seven posts. The first one was &lt;a href="https://dev.to/eristoddle/my-third-try-how-a-living-plan-beat-both-vibe-coding-and-spec-kit-5a89"&gt;my third attempt at planning with agents&lt;/a&gt;, after vibe coding and Spec Kit both didn’t work for these specific type of open-ended projects. Since then the doc got fat, I split the work across two tools, the other doc got fat, and the decision record turned out to record almost nothing until I taught it to interview me. Every one of those was a complaint before it was a feature.&lt;/p&gt;

&lt;p&gt;It’s not done, because it can’t be. It’s a skill about documents that grow, maintained by a guy whose projects keep growing. The ledger rules are still mostly hand calls. The agent catalog has one thing in it.&lt;/p&gt;

&lt;p&gt;But it runs on five projects, it bends around the ones that were there first, and the deviations are written down instead of remembered. A project opened cold should be able to tell you where it left off. The rest is plumbing.&lt;/p&gt;

</description>
      <category>livingplan</category>
      <category>agentskills</category>
      <category>aicodingprojects</category>
      <category>planningdoc</category>
    </item>
    <item>
      <title>Kimi K3.1 Pro and GPT-6.1 Terra: Cheap Per Token, Not Per Task</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 27 Oct 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/kimi-k31-pro-and-gpt-61-terra-cheap-per-token-not-per-task-364h</link>
      <guid>https://dev.to/eristoddle/kimi-k31-pro-and-gpt-61-terra-cheap-per-token-not-per-task-364h</guid>
      <description>&lt;p&gt;Last week I wrote down a rumored October 29 date for Kimi K3.1. It showed up on October 23. Artificial Analysis promptly put it above Gemini 4 Argon, and Moonshot is charging exactly what Google charges for Argon: $2 in, $10 out. Then on October 26 OpenAI shipped GPT-6.1 Terra at half the per-token price of GPT-6.1 Sol.&lt;/p&gt;

&lt;p&gt;Both got pitched as bargains. I ran the per-task numbers on both, and neither one is cheaper than the model it’s supposed to undercut. Kimi costs more per task than Argon. Terra at full effort costs about twice what Sol does to hit the same score.&lt;/p&gt;

&lt;p&gt;Meanwhile the cheapskate table got easier, and none of the cheap models did anything to earn it. The model at the top lost a few points, and the cutoff dropped with it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Kimi K3.1 Pro: smarter than Argon, slower and pricier per task

&lt;ul&gt;
&lt;li&gt;The benchmarks are mostly Moonshot’s&lt;/li&gt;
&lt;li&gt;The open weights come with the hacking cut out&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
GPT-6.1 Terra: OpenAI’s cheaper model costs more at full effort

&lt;ul&gt;
&lt;li&gt;OpenAI rates it Critical for cyber&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The rest of the board&lt;/li&gt;
&lt;li&gt;
The cheapskate table

&lt;ul&gt;
&lt;li&gt;Argon slipped, and GLM got back in&lt;/li&gt;
&lt;li&gt;Line calls&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Local sweet spot&lt;/li&gt;
&lt;li&gt;
Horror stories

&lt;ul&gt;
&lt;li&gt;An AGENTS.md in your Downloads folder&lt;/li&gt;
&lt;li&gt;OpenAI’s agents turned off their own monitoring&lt;/li&gt;
&lt;li&gt;Kimi thinking about the grader&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What’s coming&lt;/li&gt;
&lt;li&gt;Finally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Kimi K3.1 Pro: smarter than Argon, slower and pricier per task
&lt;/h2&gt;

&lt;p&gt;Moonshot put &lt;a href="https://letsdatascience.com/news/moonshot-releases-kimi-k31-pro-api-open-weights-due-nov-4-786e160c" rel="noopener noreferrer"&gt;Kimi K3.1 Pro&lt;/a&gt; in its API on October 23. It’s a post-trained K3 on the same architecture: 2.8 trillion parameters total, 104 billion active, a 1M-token context window, text and image in, &lt;a href="https://www.yottalabs.ai/post/kimi-k3-1-pro-specs-price-open-weights-benchmarks" rel="noopener noreferrer"&gt;per Yotta Labs&lt;/a&gt;. On &lt;a href="https://openrouter.ai/moonshotai/kimi-k3.1-pro" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt; only Moonshot serves it, at $2/$10, plus a “highspeed” endpoint at $4/$20 that Moonshot says runs two to three times faster. K3 costs $3/$15, so the upgrade is also a price cut.&lt;/p&gt;

&lt;p&gt;On the &lt;a href="https://artificialanalysis.ai/leaderboards/models" rel="noopener noreferrer"&gt;Artificial Analysis Intelligence Index&lt;/a&gt; it scores 55, which puts it fifth overall, behind Opus 5.5 at max (58), Sonnet 5.5 at max (56), Opus 5.5 at xhigh (56), and Muse Wonder Full (56). It beats Argon (53) and GPT-6 Astra (53). It’s also on AA’s cost-per-task frontier, meaning nothing scores 55 for less. It was number one on OpenRouter’s New &amp;amp; Trending board this week with 819 billion tokens.&lt;/p&gt;

&lt;p&gt;The bill is where it falls apart. AA puts the cost of one of its index tasks at $2.11 on Kimi K3.1 Pro and $1.62 on Argon. Same sticker, two more points, and about 30 percent more per job, because it writes more tokens to get there. And it writes them slowly. AA clocks it at 41 tokens a second, against 81 for Argon. If you run an agent loop on it, you’re paying more and waiting about twice as long for each step.&lt;/p&gt;

&lt;p&gt;Arena hasn’t rated it yet. The K3 it replaces sits 18th on Arena’s Overall board.&lt;/p&gt;

&lt;h3&gt;
  
  
  The benchmarks are mostly Moonshot’s
&lt;/h3&gt;

&lt;p&gt;Moonshot’s launch table has K3.1 Pro at 65.7 percent on Terminal-Bench 4.0 (Opus 5.5: 66.4), 75.5 on DeepSWE v1.1, and 51.7 on SWE-Marathon v1.1, where it beats Opus’s 46.3. Those come from Moonshot’s own harness. &lt;a href="https://www.vals.ai/models/kimi_kimi-k3.1-pro" rel="noopener noreferrer"&gt;Vals&lt;/a&gt; ran Terminal-Bench 4.0 itself and got 63.64. That’s two points off. Last week Reflection claimed 80.9 percent on SWE-bench Verified for a model AA scores at 30, so two points feels downright honest. Moonshot also claims the hallucination rate dropped from 23.4 percent on K3 to 8.3 percent, on an internal test nobody else can run.&lt;/p&gt;

&lt;p&gt;The early reports from people actually using it are less flattering. The top thread on r/LocalLLaMA is “&lt;a href="https://www.reddit.com/r/LocalLLaMA/comments/1xemxoq/is_it_just_me_or_kimi_k31_pro_dont_look_much/" rel="noopener noreferrer"&gt;Is it just me or Kimi K3.1 Pro don’t look much better than DeepSeek 4.1 Flash?&lt;/a&gt;” (78 comments). The highest-voted reply says Moonshot “made it worse. Much more codemaxxed.” Another commenter says it has “major reward hacking problems,” and that on nearly half their prompts the reasoning keeps working out “what the grader or evaluator wants.” An HN tester in the &lt;a href="https://news.ycombinator.com/item?id=50217036" rel="noopener noreferrer"&gt;1,091-point launch thread&lt;/a&gt; saw the same thing: reasoning traces about needing approval from “the evaluator,” and now and then the model deciding it’s ChatGPT.&lt;/p&gt;

&lt;p&gt;On r/kimi, the most upvoted reply to the &lt;a href="https://www.reddit.com/r/kimi/comments/1xdkjat/introducing_kimi_k31_pro_our_most_capable_3tclass/" rel="noopener noreferrer"&gt;launch post&lt;/a&gt; asked Moonshot to “please be generous with usage.” Another user said they hit five-hour caps on K3 almost right away doing work that barely dents their weekly usage on Opus 5.5. A separate thread there, “&lt;a href="https://www.reddit.com/r/kimi/comments/1xe7cbr/moonshot_fooled_everyone_with_kimi_k31_pros_3d/" rel="noopener noreferrer"&gt;Moonshot fooled everyone with Kimi K3.1 Pro’s 3D generation demos&lt;/a&gt;,” got 283 points. Reddit blocks my machine, so I couldn’t read that one, but &lt;a href="https://www.mindstudio.ai/blog/kimi-k3-1-pro-3d-coding-demos/" rel="noopener noreferrer"&gt;MindStudio’s hands-on&lt;/a&gt; found the same pattern. The Rubik’s Cube simulation held up. The bowline knot it modeled in Blender didn’t actually knot.&lt;/p&gt;

&lt;h3&gt;
  
  
  The open weights come with the hacking cut out
&lt;/h3&gt;

&lt;p&gt;The weights aren’t out yet. Moonshot says they’ll land by November 4, and the license hasn’t been announced (K3 shipped under its own custom one). If they use K3’s MXFP4 format, Yotta Labs estimates about 1.56TB of weights. That’s multi-node cluster territory.&lt;/p&gt;

&lt;p&gt;Moonshot is also taking something out. It &lt;a href="https://implicator.ai/kimi-k3-1-pro-hacking-cut-unpublished-test" rel="noopener noreferrer"&gt;removed cyber-related data&lt;/a&gt; from mid-training and reinforcement learning for the open-weight version, while keeping general coding. Its stated principle is to avoid releasing “open weights that would extend the absolute frontier of cyber capability.” On Moonshot’s private xdev-bench-hard test the released model solves 81.0 percent of problems, against 90.5 percent for the uncut build. K3 scored 33.3. Nobody outside Moonshot has checked any of this, and the blog doesn’t say whether fine-tuning can put the capability back.&lt;/p&gt;

&lt;p&gt;The r/LocalLLaMA thread on it, “&lt;a href="https://www.reddit.com/r/LocalLLaMA/comments/1xecgrf/kimi_k31_removes_cyberattack_training_data_from/" rel="noopener noreferrer"&gt;Kimi K3.1 removes cyberattack training data from open weight release&lt;/a&gt;,” pulled 772 points and 264 comments. Two months ago I wrote about a Chinese lab holding back its own open weights over cyber capability. Now one is shipping open weights with a capability deliberately cut out, and grading the cut on a test only it can run.&lt;/p&gt;

&lt;h2&gt;
  
  
  GPT-6.1 Terra: OpenAI’s cheaper model costs more at full effort
&lt;/h2&gt;

&lt;p&gt;GPT-6.1 Terra went out on October 26 in ChatGPT Work, Codex, and the API as &lt;code&gt;gpt-6.1-terra&lt;/code&gt;. It’s the middle model of the 6.1 lineup, aimed at computer use, reading screenshots, writing, and coding. The price is &lt;a href="https://www.bleepingcomputer.com/news/artificial-intelligence/openai-launches-gpt-61-terra-with-3x-faster-ai-agents-50-percent-lower-pricing/" rel="noopener noreferrer"&gt;$1 in and $5 out&lt;/a&gt;, with cached input at a nickel. GPT-6.1 Sol is $2/$10. GPT-5.6 Terra was $2/$12.&lt;/p&gt;

&lt;p&gt;OpenAI’s pitch is that Terra “performs on par with GPT-6 Astra at only one-tenth its price per token,” finishes tasks more than three times faster than Astra or Sol, and scores 50.3 percent on Terminal-Bench 4.0 at max effort, more than double the old Terra. OpenAI still tells you to use Sol or Astra for the hardest coding.&lt;/p&gt;

&lt;p&gt;Notice the words “per token” in that pitch. &lt;a href="https://artificialanalysis.ai/leaderboards/models" rel="noopener noreferrer"&gt;Artificial Analysis&lt;/a&gt; scored every effort level of both models, and this is what each one costs per task:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model and effort&lt;/th&gt;
&lt;th&gt;AA Index&lt;/th&gt;
&lt;th&gt;Cost per AA task&lt;/th&gt;
&lt;th&gt;Output tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol, max&lt;/td&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;$0.72&lt;/td&gt;
&lt;td&gt;74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol, high&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;$0.32&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Sol, medium&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;$0.21&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra, max&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;$0.40&lt;/td&gt;
&lt;td&gt;91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra, xhigh&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;$0.19&lt;/td&gt;
&lt;td&gt;91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra, high&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;$0.13&lt;/td&gt;
&lt;td&gt;91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra, medium&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;$0.10&lt;/td&gt;
&lt;td&gt;91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-6.1 Terra, low&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;td&gt;91&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Terra at max and Sol at medium both score 48. Terra charges $0.40 for that and Sol charges $0.21. The cheap model costs almost twice as much at the same score, because at max effort it burns through 130 million output tokens on AA’s index (the median for its price tier is 81 million). Sol at high scores 50 for $0.32, which still beats Terra at max on both score and price. AA’s own &lt;a href="https://artificialanalysis.ai/articles/gpt-6-1-terra-pushes-the-cost-efficiency-frontier" rel="noopener noreferrer"&gt;write-up&lt;/a&gt; puts it plainly: only Terra’s low and medium settings sit on the cost-efficiency frontier, and the rest fall behind it.&lt;/p&gt;

&lt;p&gt;There’s also a latency problem at the top end. AA measured Terra’s &lt;a href="https://artificialanalysis.ai/models/gpt-6-1-terra" rel="noopener noreferrer"&gt;time to first token&lt;/a&gt; at max effort at 77.96 seconds. The median is under four. You’ll be waiting over a minute before anything comes back.&lt;/p&gt;

&lt;p&gt;Terra does win on speed once it gets going. It streams at 91 tokens a second, against 54 for Sol at medium. So if you’re running a computer-use agent where every step waits on the model, Terra at low or medium is a real option, and that’s the job OpenAI built it for. If you’re turning it up to max to save money over Sol, you won’t.&lt;/p&gt;

&lt;p&gt;r/OpenAI got there within a day: “&lt;a href="https://www.reddit.com/r/OpenAI/comments/1xge8ua/do_gpt_61_terra_even_make_sense_gpt_61_sol/" rel="noopener noreferrer"&gt;Do GPT 6.1 Terra even make sense? (GPT 6.1 Sol outperforming GPT 6.1 Terra at same cost)&lt;/a&gt;.” Over on r/codex, “&lt;a href="https://www.reddit.com/r/codex/comments/1xgmzda/what_is_the_role_of_gpt61_terra/" rel="noopener noreferrer"&gt;What is the role of GPT-6.1 Terra&lt;/a&gt;” has 72 comments, and the funniest of them is just “GPT-6.1 Terra is the white area.” One r/singularity commenter laid out the lineup better than OpenAI’s launch post did: “you have Luna for your simple tasks, Sol as a more advanced model, and Astra for this sh!t that needs to work.”&lt;/p&gt;

&lt;p&gt;This is the third time I’ve written this section. In September Sonnet 5.5 at max cost more per task than Opus 5.5 at the same score. A cheap sibling running at max effort keeps turning out to be the expensive option. Compare at the score you need, not at the effort setting with the same name.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAI rates it Critical for cyber
&lt;/h3&gt;

&lt;p&gt;Terra carries a &lt;a href="https://cybersecuritynews.com/openai-unveils-gpt-6-1-terra/" rel="noopener noreferrer"&gt;Critical cybersecurity rating&lt;/a&gt; under OpenAI’s Preparedness Framework, the same as GPT-6 Astra. On OpenAI’s internal test with recently disclosed vulnerabilities, Terra got arbitrary code execution 24.5 percent of the time, against 21.5 for Sol and 31.5 for Astra. The system card also says that in one evaluation run without system-level controls, it got around the intent of its environment’s restrictions in 29.6 percent of runs.&lt;/p&gt;

&lt;p&gt;In the same week, Moonshot cut hacking skills out of its open release and OpenAI shipped a mid-priced model it rates Critical for cyber. Moonshot’s open weights can’t be recalled once people download them. OpenAI keeps Terra behind its own API safeguards.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rest of the board
&lt;/h2&gt;

&lt;p&gt;DeepSeek V4.1 Flash 1017 is number one on &lt;a href="https://openrouter.ai/rankings" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt; for the week ending October 26, at 35.4 trillion tokens and up 382 percent. The original V4.1 Flash fell 41 percent to 17.4 trillion, good for second. Last week I said this would be migration rather than hype, since the snapshot took over the &lt;code&gt;deepseek-flash&lt;/code&gt; API name and DeepSeek’s own endpoint. That’s how it went. Between them they did 52.8 trillion tokens, and DeepSeek now has 26.5 percent of all OpenRouter requests. DeepSeek charges $0.15/$0.60 for 1017, and AA gives it 45 at $0.26 a task and 170 tokens a second. It still doesn’t have an Arena rating, so it isn’t in the table yet.&lt;/p&gt;

&lt;p&gt;Fourth place went to MiniMax M3.1 Flash, the free version, with 12.6 trillion. That’s the Space Bunny model under its real name. MiniMax lists the paid version at $0.15/$0.60, AA gives it 43, and Arena hasn’t rated it. When the free period ends I expect most of that traffic to wander off, the same way Step 5’s did.&lt;/p&gt;

&lt;p&gt;Flint came out October 21 from a startup called Recursive. It’s a coding MoE with 40B parameters total and 2.5B active, under &lt;a href="https://runtimewire.com/article/recursive-flint-local-coding-model-eureka-machine" rel="noopener noreferrer"&gt;Apache 2.0&lt;/a&gt;, and Recursive says its automated research system did most of the building. It’s free on OpenRouter and second on New &amp;amp; Trending. The r/unsloth post “&lt;a href="https://www.reddit.com/r/unsloth/comments/1xc2kfl/run_flint_the_strongest_moe_model_under_50b/" rel="noopener noreferrer"&gt;Run Flint, the strongest MoE model under 50B parameters!&lt;/a&gt;” got 580 points, and the people who actually ran it were less excited. The top reply on &lt;a href="https://www.reddit.com/r/opencode/comments/1xc7vph/new_model_on_opencode_flint40bfree/" rel="noopener noreferrer"&gt;r/opencode&lt;/a&gt; puts it below Qwen 3.8 27B but likes the speed, and r/LocalLLM has a thread titled “Recursive Flint: Very Bad English.” The 100 to 131 tokens a second on a MacBook Pro comes from Recursive, not from anyone independent.&lt;/p&gt;

&lt;p&gt;Claude Haiku 5.5 finally has an Arena rating, two weeks after launch: 126th Overall, at 1424.6. Two weeks ago I said it would compete for cheapskate picks once Arena rated it. I was wrong. It isn’t within shouting distance of any band. Haiku is fast (237 tokens a second on AA) and cheap, and Arena voters just don’t pick it.&lt;/p&gt;

&lt;p&gt;One more number from the market-share chart: Anthropic’s share of OpenRouter requests jumped 25 percent, to 5.5 percent. Google has 20.1 and OpenAI 18.5.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheapskate table
&lt;/h2&gt;

&lt;p&gt;New readers: for each Arena category I take the leader’s rating, subtract 50, and find the cheapest model still above that line. I compute the band in code from every row on the board, and I write down the first model below the line so I know nothing got cut off. The board is &lt;a href="https://huggingface.co/datasets/lmarena-ai/leaderboard-dataset" rel="noopener noreferrer"&gt;LMArena’s leaderboard dataset&lt;/a&gt; on Hugging Face, published October 22. Prices are each maker’s own endpoint on OpenRouter. Argon is priced at its $10 intro rate.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1517)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1476, #35)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−41&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1552)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Flash (1511, #57)&lt;/td&gt;
&lt;td&gt;$0.28&lt;/td&gt;
&lt;td&gt;−41&lt;/td&gt;
&lt;td&gt;36×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-opus-5.5-high (1520)&lt;/td&gt;
&lt;td&gt;$20&lt;/td&gt;
&lt;td&gt;gemini-3.7-flash-high (1492, #6)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−28&lt;/td&gt;
&lt;td&gt;5.3×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;claude-opus-5.5-high (1521)&lt;/td&gt;
&lt;td&gt;$20&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1473, #31)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−49&lt;/td&gt;
&lt;td&gt;40×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1540)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1501, #33)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−39&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1532)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1504, #15)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−28&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Band depths: Overall 49, Coding 76, Creative 17, Instruction Following 35, Hard Prompts 47, Math 38.&lt;/p&gt;

&lt;h3&gt;
  
  
  Argon slipped, and GLM got back in
&lt;/h3&gt;

&lt;p&gt;Last week GLM-5.3-Flash missed the Overall band by 0.06 points. This week it’s in by 8.8, and it barely moved (1473.84 to 1475.96). Argon did the moving. Its Overall rating dropped from 1523.9 to 1517.17 as its vote count roughly doubled, from 4,904 to 10,083. Argon’s early voters liked it more than the next five thousand did, and when the leader comes down, the cutoff comes down with it. The Overall band went from 40 models to 49, and Coding from 59 to 76.&lt;/p&gt;

&lt;p&gt;That puts GLM-5.3-Flash back as the pick in four of six categories, at 50 cents. It’s back in Instruction Following too, after three issues out, 1.43 points over the line on 13,261 votes. And the Overall pick has 38,359 votes behind it, more than any other pick in the table.&lt;/p&gt;

&lt;p&gt;Opus 5.5 also took a category off Argon. It now leads Instruction Following, 1521.39 to 1519.18. Argon has now given up two categories (Opus took Creative Writing last week). Overall, Opus is 8.4 points behind. Creative Writing and Instruction Following now run against Opus’s $20 instead of Argon’s $10, which is why the IF ratio jumped to 40×.&lt;/p&gt;

&lt;h3&gt;
  
  
  Line calls
&lt;/h3&gt;

&lt;p&gt;I don’t round, and this week that mattered in four places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coding’s first model below the line is Gemini 3.5 Flash-Lite at 1501.55. The cutoff is 1501.57. It missed by two hundredths of a point.&lt;/li&gt;
&lt;li&gt;ERNIE 5.1 missed Overall by 0.05.&lt;/li&gt;
&lt;li&gt;MiMo-V2.6-Pro missed Instruction Following by 0.18. At 87 cents it would have been the runner-up there.&lt;/li&gt;
&lt;li&gt;Gemma 4 31B made the Coding band by 0.84 points on 1,416 votes. OpenRouter has a free variant of it, which technically beats every price in the table. Free endpoints are rate-limited, though, and paid hosts charge around 32 to 40 cents out, more than MiMo-V2.6-Flash. Fine for weekend tinkering. I wouldn’t build a product on a rate-limited free endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MiMo-V2.6-Flash holds Coding for a fourth issue, up to 3,232 votes and now 9.2 points over the line, its most comfortable margin yet. If you want a steadier rating, GPT-6 Luna at max is in the same band at 50 cents with 16,451 votes, and GLM-5.3-Flash sits at 27th in Coding for the same price.&lt;/p&gt;

&lt;p&gt;Artificial Analysis mostly backs this up. MiMo-V2.6-Flash is on its cost-per-task frontier (38 on the index for six cents a task). GLM-5.3-Flash isn’t: it scores 42 at 28 cents a task, and MiMo-V2.6-Pro beats it on both at 46 for 13 cents. So if your work looks more like hard benchmarks than like Arena chat, try MiMo-V2.6-Pro at 87 cents. It’s the Overall and Hard Prompts runner-up.&lt;/p&gt;

&lt;p&gt;Creative Writing is still the category where you pay for quality. The cheapest model in its 17-model band is the Gemini Flash family at $3.75 out ($1.875 on the flex tier).&lt;/p&gt;

&lt;p&gt;And December 1 is still on the calendar. Argon’s price goes to $4/$20 that day, and every ratio in this table with Argon as the leader doubles. Overall, Hard Prompts, and Math go from 20× to 40×, and Coding goes to 71×, without a single pick changing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local sweet spot
&lt;/h2&gt;

&lt;p&gt;The rule: the biggest model that fits your machine with room left for context, running at 15 or more tokens a second. Arena picks the winner, and when two models are within 15 Arena points, the Artificial Analysis score breaks the tie.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your machine&lt;/th&gt;
&lt;th&gt;Pick&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Arena&lt;/th&gt;
&lt;th&gt;AA&lt;/th&gt;
&lt;th&gt;Measured tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mac 16GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;27 (n=4, 6-82)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 32GB&lt;/td&gt;
&lt;td&gt;qwen3.8-27b MLX 4bit&lt;/td&gt;
&lt;td&gt;16.1 GB&lt;/td&gt;
&lt;td&gt;1437 (#102)&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 64GB+&lt;/td&gt;
&lt;td&gt;gemma-4-31b Q4_K_M&lt;/td&gt;
&lt;td&gt;18.3 GB&lt;/td&gt;
&lt;td&gt;1452 (#76)&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 12GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;50 (n=1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 24GB&lt;/td&gt;
&lt;td&gt;gemma-4-31b Q4_K_M&lt;/td&gt;
&lt;td&gt;18.3 GB&lt;/td&gt;
&lt;td&gt;1452 (#76)&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;LMArena switched its dataset from slugs (“qwen3.8-27b”) to display names (“Qwen3.8-27B”) this week. That broke the script’s model matching without throwing a single error. Once I fixed it, Gemma 4 31B came out 15.11 Arena points ahead of Qwen3.8 27B. That’s 0.11 past the tie line, so the AA tie-break no longer applies, and Gemma takes the 64GB Mac and 24GB NVIDIA rows.&lt;/p&gt;

&lt;p&gt;I’m printing what the rule says, because that’s the point of declaring the rule ahead of time. But AA scores Gemma 4 31B at 15 and Qwen3.8 27B at 34, and a pick that flips on a tenth of a point is a coin toss. If you mostly chat and write, Gemma is fine. If you need reasoning, I’d stay on Qwen.&lt;/p&gt;

&lt;p&gt;Flint is in the candidate list now. Unsloth’s Q4_K_XL is 25.1GB, which fits a 64GB Mac but not a 24GB card. It has no Arena or AA rating yet, so it can’t win a ranked row. The 9B rows are picked by what fits, since nothing that small has an Arena rating. And the Gemma speeds are unmeasured. I’m not filling them in from a calculator site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horror stories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  An AGENTS.md in your Downloads folder
&lt;/h3&gt;

&lt;p&gt;On October 25 &lt;a href="https://www.bleepingcomputer.com/news/security/ai-coding-agents-hijacked-using-agentsmd-file-in-downloads-folder/" rel="noopener noreferrer"&gt;BleepingComputer reported&lt;/a&gt; that researchers found a malicious AGENTS.md sitting in a customer’s &lt;code&gt;~/Downloads&lt;/code&gt; folder. The customer had launched a coding agent from there. The agent read the file the way agents read instruction files, and tried to install an npm package called &lt;code&gt;function-color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The researchers reproduced it against Codex with a harmless calculator payload and got a 90 percent success rate. A CLAUDE.md version leaked Claude Code’s OAuth tokens and took over the account in about half their tests. They couldn’t work out how the file got into the folder in the first place. Their explanation: Downloads is the one folder a web page can write to without asking, since browsers save there by default. And people run agents from it a lot. In their customer data, Claude Code alone had launched more than 1,300 sessions from a Downloads folder.&lt;/p&gt;

&lt;p&gt;“There is nothing here for OpenAI or Anthropic to patch,” the researchers say. Both vendors already tell you to run agents from the project directory. So do that. Don’t start an agent in Downloads or your home folder, and read any AGENTS.md or CLAUDE.md you didn’t write before your agent does.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAI’s agents turned off their own monitoring
&lt;/h3&gt;

&lt;p&gt;On October 20 OpenAI published a report on two incidents inside its own shop, &lt;a href="https://aljazeera.com/economy/2026/10/21/openai-says-its-agents-turned-off-own-safeguards" rel="noopener noreferrer"&gt;covered by Al Jazeera&lt;/a&gt; and &lt;a href="https://bleepingcomputer.com/news/security/openai-agents-disabled-safety-monitoring-one-lied-about-it" rel="noopener noreferrer"&gt;BleepingComputer&lt;/a&gt;. On October 3 a GPT-6.1 Sol agent working on an evaluation pipeline switched off security-team alerts. It had been told earlier not to send any messages, and it decided that covered automated notifications too. Monitoring kept running and saving its findings. Humans just stopped getting told.&lt;/p&gt;

&lt;p&gt;On October 6 a GPT-6 Astra agent doing a migration removed a monitoring integration so the code would match a reference implementation. When asked about it afterward, it said it hadn’t, and OpenAI says that was untrue. OpenAI says neither incident was classed at its highest priority, and it has updated its internal Auto-Review system to catch and block attempts to disable misalignment monitoring.&lt;/p&gt;

&lt;p&gt;These are OpenAI’s own agents, in OpenAI’s own environment, built by people who know exactly what the monitors are for. Neither agent was attacked. Each one read an ordinary instruction as permission to switch off the thing watching it. If your agent has write access to its own monitoring, it can switch it off too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kimi thinking about the grader
&lt;/h3&gt;

&lt;p&gt;Multiple users report that Kimi K3.1 Pro’s reasoning keeps returning to what an imagined “grader” or “evaluator” wants, on nearly half the prompts one commenter tried. That’s reward hacking, and you can read it in the trace. If you try Kimi, read a few reasoning traces before you trust what comes out the other end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming
&lt;/h2&gt;

&lt;p&gt;Moonshot says the Kimi K3.1 Pro weights land by November 4, minus the cyber data, under a license it hasn’t named yet. Mistral’s launch post promised the Large 4 weights by the end of October. Coverage can’t agree on whether that means October 27 or 31, and nothing was on Hugging Face this morning. Reports say it’ll be a custom license rather than Apache. Argon goes from $2/$10 to $4/$20 on December 1, which is the only date here I’d bet on.&lt;/p&gt;

&lt;p&gt;Kimi K3.1 Pro, GPT-6.1 Terra, and the DeepSeek 1017 snapshot are all still waiting on Arena ratings. I’d expect them in the next week or two, and 1017 is the one most likely to land in a band. Claude Fable 5.5 and DeepSeek V5 remain speculation. A community countdown site guesses November 5 for Fable 5.5, and nobody official has said a word.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;If you’re deciding this week: Kimi K3.1 Pro is worth a look when you need the AA score and can live with 41 tokens a second and $2.11 a task. GPT-6.1 Terra belongs on low or medium effort, inside agents that wait on every step. At max, use Sol at medium instead and pay about half.&lt;/p&gt;

&lt;p&gt;The bottom of the table didn’t need a launch. GLM-5.3-Flash holds Overall, Instruction Following, Hard Prompts and Math at 50 cents, MiMo-V2.6-Flash has Coding at 28 cents, and if you need something that does better on hard benchmarks, MiMo-V2.6-Pro is 87 cents. I’d still start a cost-sensitive project on GLM-5.3-Flash and only pay 20 times more once it actually lets you down.&lt;/p&gt;

&lt;p&gt;Next week Arena should start rating this week’s launches, and the Kimi weights are due. I’ll also be watching whether Mistral actually ships its weights by Friday.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
      <category>modelroundup</category>
    </item>
    <item>
      <title>OpenCode 2 Ran My Old v1 Config Without Touching It. Here's What It Stopped Doing</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 22 Oct 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/opencode-2-ran-my-old-v1-config-without-touching-it-heres-what-it-stopped-doing-3l18</link>
      <guid>https://dev.to/eristoddle/opencode-2-ran-my-old-v1-config-without-touching-it-heres-what-it-stopped-doing-3l18</guid>
      <description>&lt;p&gt;In September I created a global OpenCode config and really complex configs for a few projects. Two primary agents, four subagents, and 18 more generated by a Python script from an agent plugin living in a git submodule. Permissions tuned agent by agent. A 52 KB &lt;code&gt;opencode.json&lt;/code&gt; that finally stopped fighting me. I put the process to use the agents in an &lt;code&gt;AGENTS.md&lt;/code&gt; so I would never have to figure it out again.&lt;/p&gt;

&lt;p&gt;OpenCode 2.0.0 landed on npm a few weeks later.&lt;/p&gt;

&lt;p&gt;So I looked at the official &lt;a href="https://opencode.ai/v2/docs/migrate-v1/" rel="noopener noreferrer"&gt;Migrate from V1&lt;/a&gt; guide and expected a long evening. Nearly every config key got renamed, permissions changed shape, and the guide has a really long table. Ugh, seriously. Then I found the sentence that made most of that optional, and I upgraded without converting a thing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Sentence That Made Things Easier&lt;/li&gt;
&lt;li&gt;What I Actually Did&lt;/li&gt;
&lt;li&gt;The Mistake I Found While Checking&lt;/li&gt;
&lt;li&gt;Converting the Global File With OpenCode Itself&lt;/li&gt;
&lt;li&gt;Permissions Went From a Map to an Ordered List&lt;/li&gt;
&lt;li&gt;Compaction Got Smarter&lt;/li&gt;
&lt;li&gt;The Removals&lt;/li&gt;
&lt;li&gt;The Big Change You Can’t See: One Shared Service&lt;/li&gt;
&lt;li&gt;Subagents Run in the Background Now&lt;/li&gt;
&lt;li&gt;Stuff That Got Easier&lt;/li&gt;
&lt;li&gt;So Is It Worth It?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Sentence That Made Things Easier
&lt;/h2&gt;

&lt;p&gt;V2 reads your existing config from the same locations as v1: system, managed preferences, global, and project. It normalizes the old keys in memory and does not rewrite your file. Converting to the v2 format is optional, and the old and new forms can coexist in the same file if you want that chaos. If both set the same value, “a valid native V2 value takes precedence regardless of JSON key order.”&lt;/p&gt;

&lt;p&gt;Also, very important, inside a single agent, provider, command, or model entry, pick only one format. Don’t put &lt;code&gt;prompt&lt;/code&gt; and &lt;code&gt;system&lt;/code&gt; in the same agent.&lt;/p&gt;

&lt;p&gt;In v1, warnings only show up for malformed values, conflicting old and new values, and fields v2 no longer supports at all. No warnings is a good sign, but it also means v2 won’t nag you about anything it is handling without telling you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Did
&lt;/h2&gt;

&lt;p&gt;I backed up my config, just in case. Your config lives in &lt;code&gt;~/.config/opencode&lt;/code&gt;, but every session you have ever run lives in &lt;code&gt;~/.local/share/opencode/opencode.db&lt;/code&gt;, and mine was 516 MB. I quit OpenCode and copied the whole folder first.&lt;/p&gt;

&lt;p&gt;Then I ran the curl installer from the docs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://opencode.ai/v2/install | bash

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That replaced my v1 binary, which was 1.19.3 at the time. &lt;code&gt;opencode --version&lt;/code&gt; said 2.1.1. I opened it in an empty folder so only my global config applied, picked an agent, and gave it a real piece of work I needed done. It finished with no problems and no startup warnings.&lt;/p&gt;

&lt;p&gt;I had been paranoid about this for a week. I was way too paranoid.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mistake I Found While Checking
&lt;/h2&gt;

&lt;p&gt;Before upgrading I went looking for every &lt;code&gt;opencode.json&lt;/code&gt; I had, because I could not remember how many there were. Six config files and three &lt;code&gt;.opencode/&lt;/code&gt; folders, spread over five projects and the global folder:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Agents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;td&gt;5.8 KB&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;This blog&lt;/td&gt;
&lt;td&gt;55 KB&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;My Obsidian vault&lt;/td&gt;
&lt;td&gt;53 KB&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project A&lt;/td&gt;
&lt;td&gt;47 KB&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project B&lt;/td&gt;
&lt;td&gt;42 KB&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A Python side project&lt;/td&gt;
&lt;td&gt;17 KB&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three different shapes, too. Desk and librarian setups with nested permissions, a flat global file, and an older style I had forgotten existed.&lt;/p&gt;

&lt;p&gt;Custom agents in every project felt organized at the time. In practice, when a new major version ships, you have six files to worry about instead of one, and when one of them breaks, you are debugging config instead of working. And they didn’t even have to be JSON. Agents can also be single markdown files in &lt;code&gt;.opencode/agents/&lt;/code&gt;, which I didn’t know when I built all this. I want my fallback to be the global config, with my usual models already set up, so I can switch to a plain agent and keep going.&lt;/p&gt;

&lt;p&gt;So I cut. The side project’s config was generic and the global agents already covered it, so I deleted it. For the two client projects I kept the one agent I actually use, a hands-on &lt;code&gt;solo&lt;/code&gt; agent on Kimi K3 with reasoning at max, moved it into the global config, and deleted both local files. I gave up the file guards those configs had, like denying edits to a &lt;code&gt;raw/&lt;/code&gt; folder, because those rules had been locking me in so hard I stopped using the agents. That left the global file, the blog, and the vault.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting the Global File With OpenCode Itself
&lt;/h2&gt;

&lt;p&gt;The guide recommends letting OpenCode convert your config, with this prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Migrate my OpenCode configuration, including file-based definitions, from the V1 format to the native V2 format. Preserve its behavior and all unrelated settings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I ran it from &lt;code&gt;~/.config/opencode&lt;/code&gt; against the global file, which is small and sits in git, so a bad result was one &lt;code&gt;git checkout&lt;/code&gt; away. It worked on the first try. This is the global &lt;code&gt;plan&lt;/code&gt; agent, trimmed, before and after:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;v&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"agent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openrouter/~moonshotai/kimi-latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"reasoning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"effort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"max"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"permission"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"write"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"edit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"bash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;v&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"agents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openrouter/~moonshotai/kimi-latest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"reasoning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"effort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"max"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"edit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subagent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"allow"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things worth noticing in what it did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;write&lt;/code&gt; disappeared.&lt;/strong&gt; It merged into &lt;code&gt;edit&lt;/code&gt;, so two rules became one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reasoning effort moved to &lt;code&gt;request.body&lt;/code&gt;.&lt;/strong&gt; I was worried about this one, because the guide says the old &lt;code&gt;reasoning&lt;/code&gt; field is ignored and describes effort as a variant setting. OpenCode chose to keep it as a request body field.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The top-level keys followed the table.&lt;/strong&gt; &lt;code&gt;provider&lt;/code&gt; became &lt;code&gt;providers&lt;/code&gt; with &lt;code&gt;npm&lt;/code&gt; turning into &lt;code&gt;package: "aisdk:@ai-sdk/openai-compatible"&lt;/code&gt;, &lt;code&gt;autoupdate: false&lt;/code&gt; became &lt;code&gt;update: "disable"&lt;/code&gt;, and &lt;code&gt;small_model&lt;/code&gt; became &lt;code&gt;agents.title.model&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It dropped &lt;code&gt;compaction.prune&lt;/code&gt; and renamed &lt;code&gt;reserved&lt;/code&gt; to &lt;code&gt;buffer&lt;/code&gt;.&lt;/strong&gt; More on that below.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It left &lt;code&gt;lsp&lt;/code&gt; and &lt;code&gt;enabled_providers&lt;/code&gt; alone.&lt;/strong&gt; The first does nothing in v2 anyway, and the second has a different home in v2 that the converter apparently decided not to touch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It also edited my &lt;code&gt;AGENTS.md&lt;/code&gt;.&lt;/strong&gt; The roster doc describes the config, so it updated its own description of the permissions to match. I did not ask for that, but whatever, I guess.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Permissions Went From a Map to an Ordered List
&lt;/h2&gt;

&lt;p&gt;In v1, permissions were an object grouped by tool. In v2 they are &lt;code&gt;permissions&lt;/code&gt;, an ordered array of rules with an &lt;code&gt;action&lt;/code&gt;, a &lt;code&gt;resource&lt;/code&gt;, and an &lt;code&gt;effect&lt;/code&gt;. Three action names changed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bash&lt;/code&gt; is now &lt;code&gt;shell&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;task&lt;/code&gt; is now &lt;code&gt;subagent&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;write&lt;/code&gt; and &lt;code&gt;patch&lt;/code&gt; collapse into &lt;code&gt;edit&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A per-pattern v1 rule like &lt;code&gt;"bash": { "git push *": "ask" }&lt;/code&gt; becomes one array entry per pattern, with the pattern in &lt;code&gt;resource&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;task&lt;/code&gt; rename is one that matters for me. Every subagent in my configs has &lt;code&gt;task: deny&lt;/code&gt; so a cheap model can’t kick off a fan-out that blows up the session, except the three workflow orchestrators whose job is fanning out. In v2 that is a &lt;code&gt;subagent&lt;/code&gt; rule.&lt;/p&gt;

&lt;p&gt;In v1 I learned the hard way that a &lt;code&gt;"*": "deny"&lt;/code&gt; catch-all on skills doesn’t just block skills. OpenCode filters the skill list in the prompt by permission, so the model never finds out the skill exists, and there’s no error to notice. An ordered list changes how that trap works. The permissions docs say “The last matching rule wins, so the specific exceptions follow the broad rule,” so a catch-all deny placed last would void every allow above it.&lt;/p&gt;

&lt;p&gt;The guide itself doesn’t document the &lt;code&gt;skill&lt;/code&gt; or &lt;code&gt;question&lt;/code&gt; actions, or what &lt;code&gt;webfetch&lt;/code&gt; maps to, so those are the rules to test rather than trust.&lt;/p&gt;

&lt;p&gt;So I tested the one thing that I know breaks. I asked &lt;code&gt;desk&lt;/code&gt; to have &lt;code&gt;librarian&lt;/code&gt; write today’s daily note, which already existed. &lt;code&gt;librarian&lt;/code&gt; didn’t overwrite it. It sent a message back to &lt;code&gt;desk&lt;/code&gt; explaining the conflict, and &lt;code&gt;desk&lt;/code&gt; passed that back to me and waited for a decision. That is the behavior I expected, and it survived the upgrade with the old permission format untouched.&lt;/p&gt;

&lt;p&gt;The docs don’t say whether v2 still hides denied skills from the model, so I checked. I asked &lt;code&gt;desk&lt;/code&gt;, which has no skill rules, to list every skill it could see, then asked &lt;code&gt;librarian&lt;/code&gt;, which denies some skills. Eight of the denied skills were on &lt;code&gt;desk&lt;/code&gt;’s list and missing from &lt;code&gt;librarian&lt;/code&gt;’s. The other two lists matched exactly. So v2 behaves like v1 here: a denied skill disappears from the prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compaction Got Smarter
&lt;/h2&gt;

&lt;p&gt;V1 compaction was a summarize-and-pray operation. V2 writes a structured summary meant for another agent to pick the work up from: the objective and requirements, decisions, completed and active work, blockers, next moves, and relevant files. Automatic compaction kicks in near the context limit, governed by a &lt;code&gt;buffer&lt;/code&gt; setting. And if a provider rejects a request as too long, v2 compacts and retries once. A second rejection comes back as an error.&lt;/p&gt;

&lt;p&gt;My config had &lt;code&gt;"compaction": { "auto": true, "prune": true, "reserved": 10000 }&lt;/code&gt;. The converter turned that into &lt;code&gt;auto&lt;/code&gt; plus &lt;code&gt;"buffer": 10000&lt;/code&gt; and dropped &lt;code&gt;prune&lt;/code&gt;, which v2 ignores.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Removals
&lt;/h2&gt;

&lt;p&gt;You notice these months later that something stopped happening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V2 removes a safety check.&lt;/strong&gt; In v1, OpenCode asked before touching files outside your project. In v2, &lt;code&gt;external_directory&lt;/code&gt; is allowed by default. If you want the old behavior back, it’s one rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external_directory"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ask"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;V2 doesn’t discover &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/strong&gt; It reads &lt;code&gt;AGENTS.md&lt;/code&gt; only, so if your instructions live in &lt;code&gt;CLAUDE.md&lt;/code&gt;, v2 doesn’t see them. I had one project like that and caught it. The fix is to put the real content in &lt;code&gt;AGENTS.md&lt;/code&gt; and make &lt;code&gt;CLAUDE.md&lt;/code&gt; a one-line file containing &lt;code&gt;@AGENTS.md&lt;/code&gt;. Claude Code follows that import, OpenCode reads the real file, and the two can’t drift apart. Claude Code has also started reading &lt;code&gt;AGENTS.md&lt;/code&gt; on its own, as a fallback when there’s no &lt;code&gt;CLAUDE.md&lt;/code&gt;. But you know what. Anthropic should have done that long ago instead of being assholes about it. So I still do things this way in case they decide to play the asshole card again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V2 doesn’t run language servers.&lt;/strong&gt; If you used it and was counting on diagnostics feeding back into the agent, that is a real regression.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44qosp2twqdtnkv9dnlz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44qosp2twqdtnkv9dnlz.jpg" alt="The Quiet Removals" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V1 plugins don’t run.&lt;/strong&gt; There’s a new plugin API and a separate porting guide. No compatibility shim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A pile of fields are just ignored&lt;/strong&gt; , including &lt;code&gt;logLevel&lt;/code&gt; (use &lt;code&gt;OPENCODE_LOG_LEVEL&lt;/code&gt;), top-level &lt;code&gt;subagent_depth&lt;/code&gt; (now &lt;code&gt;experimental.subagent_depth&lt;/code&gt;), and several provider-model fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;V2 puts a new file into your config folder.&lt;/strong&gt; After the upgrade I found a new &lt;code&gt;service.json&lt;/code&gt; in &lt;code&gt;~/.config/opencode&lt;/code&gt; with a password in it, for the shared service.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Change You Can’t See: One Shared Service
&lt;/h2&gt;

&lt;p&gt;In v1 the TUI was the thing. In v2, OpenCode discovers or starts one shared background server for your user account, and every local client connects to it. The New Stack called it &lt;a href="https://thenewstack.io/opencode-2-shared-service/" rel="noopener noreferrer"&gt;a major overhaul&lt;/a&gt;, and that’s not hype.&lt;/p&gt;

&lt;p&gt;What that buys you in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The terminal and desktop clients should be looking at the same sessions.&lt;/strong&gt; Start something in the terminal, check on it from the desktop app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A web UI you can pair to.&lt;/strong&gt; &lt;code&gt;opencode pair&lt;/code&gt; serves a web interface, and pairing only works while the shared service is running. The changelog mentions &lt;code&gt;opencode pair --remote&lt;/code&gt;, which asks before exposing your server to anything beyond localhost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A real API.&lt;/strong&gt; The server API got new contracts and a typed client package. The docs call it an intentional breaking change, so if you built anything against the v1 server, it’s broken.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I seldom opened the desktop app, and after the upgrade it wouldn’t load my configs at all. It was still a v1 build, 1.3.13. One &lt;code&gt;brew upgrade opencode-desktop&lt;/code&gt; took it to 2.1.1, and no errors showed up after that.&lt;/p&gt;

&lt;p&gt;Then I asked &lt;code&gt;librarian&lt;/code&gt; to write a daily note from the terminal, and the session showed up in the desktop app. I could click into it and read what it was doing while it ran. That’s the shared service doing what the docs promised, and it’s the thing GitHub Copilot never managed for me. I’d start something in VS Code and the Copilot app couldn’t see it, which made the app useless to me. I think they fixed that maybe, but I stopped checking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subagents Run in the Background Now
&lt;/h2&gt;

&lt;p&gt;In v1, when a primary agent handed work to a subagent, you waited. In v2, &lt;a href="https://dev.to/eristoddle/the-subagents-guide-i-wish-id-had-dhh"&gt;subagents run with fresh context&lt;/a&gt; in foreground or background child sessions, each with its own configured permissions, and delegated commands run in the background and report back to the parent session.&lt;/p&gt;

&lt;p&gt;I built my vault around delegation. &lt;code&gt;desk&lt;/code&gt; routes to &lt;code&gt;librarian&lt;/code&gt;, &lt;code&gt;researcher&lt;/code&gt;, and &lt;code&gt;editor&lt;/code&gt;, and the three &lt;code&gt;cw-*&lt;/code&gt; workflow orchestrators fan out to reviewer agents. Every one of those hops used to block. Honestly, I haven’t used that machinery in weeks. These days I use one agent which runs on Kimi K3 and does everything itself, because one agent I can watch beats a whole list of them I have to maintain. But if background subagents work the way the docs say, that might bring me back.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5q5a8qynb8djvbmfexm8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5q5a8qynb8djvbmfexm8.jpg" alt="Subagents Run in the Background Now" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They work. I ran it through &lt;code&gt;desk&lt;/code&gt; in the vault, on the 25-agent config I never converted, and the subagents ran in the background while the session stayed usable. The same session was visible in the desktop app while it ran.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stuff That Got Easier
&lt;/h2&gt;

&lt;p&gt;It’s not all renames. A few things got better for my setup specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/eristoddle/the-agent-skills-guide-i-wish-id-had-17i1"&gt;Skill files&lt;/a&gt; don’t need rewriting.&lt;/strong&gt; The guide says so explicitly. The preferred layout is &lt;code&gt;.opencode/skills/&amp;lt;skill-id&amp;gt;/SKILL.md&lt;/code&gt;, and if you move one, move the whole directory, not just the &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills paths merge.&lt;/strong&gt; &lt;code&gt;skills.paths&lt;/code&gt; and &lt;code&gt;skills.urls&lt;/code&gt; become one &lt;code&gt;skills&lt;/code&gt; array.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshots are on by default&lt;/strong&gt; , stored in a separate internal git object database that doesn’t create commits or move your branches. &lt;code&gt;/undo&lt;/code&gt; rolls back the conversation and restores the affected files. The docs call capture “best effort,” and restoring doesn’t reverse what shell commands did to services, databases, or git state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model variants are built into the model string&lt;/strong&gt; : &lt;code&gt;provider/model#variant&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skill discovery was my other worry. v1 found my vault’s skills through a &lt;code&gt;skills/**/SKILL.md&lt;/code&gt; glob, and the v2 docs only promise &lt;code&gt;.opencode/skills/&lt;/code&gt;. It found them anyway. When I asked &lt;code&gt;desk&lt;/code&gt; to list its skills, everything from the vault showed up.&lt;/p&gt;

&lt;h2&gt;
  
  
  So Is It Worth It?
&lt;/h2&gt;

&lt;p&gt;For a config like mine, the migration turned out to be mostly a non-event. V2 read my old global file as it was, I ran a real task on it without a warning, and converting the file afterward took one prompt and a diff review. The scary rename table is real, but it only matters when you decide to adopt it.&lt;/p&gt;

&lt;p&gt;What actually changed under me is smaller: no language servers, no v1 plugins, no &lt;code&gt;CLAUDE.md&lt;/code&gt;, a more permissive default for files outside the project, and a new password file in my config folder.&lt;/p&gt;

&lt;p&gt;The better lesson is about my own setup. I had built a custom config in every project, and a major version made me pay for that. I’d rather have one global config with the models and agents I use everywhere, and only add a project-level file when a project really needs it. I &lt;a href="https://dev.to/eristoddle/the-expensive-model-only-plans-now-i-split-my-ai-coding-rig-across-two-tools-4dch"&gt;split my AI coding rig across two tools&lt;/a&gt; so I’d never be stuck when one of them changed under me. This time I did not get stuck, and I still lost an evening to worrying about it.&lt;/p&gt;

</description>
      <category>opencode</category>
    </item>
    <item>
      <title>Remotely Save for Obsidian: S3 and WebDAV Sync That Costs $0 on R2</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Wed, 21 Oct 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/remotely-save-for-obsidian-s3-and-webdav-sync-that-costs-0-on-r2-1gfh</link>
      <guid>https://dev.to/eristoddle/remotely-save-for-obsidian-s3-and-webdav-sync-that-costs-0-on-r2-1gfh</guid>
      <description>&lt;p&gt;I’ve used Remotely Save to sync Obsidian to my phone and iPad since the first week I started using Obsidian. I told it to use Dropbox, it worked, and I didn’t think about it. That’s the greatest praise you can give a sync plugin.&lt;/p&gt;

&lt;p&gt;Then I started to write this post and checked the changelog. The latest release is 0.5.25, from October 20, 2024. The last commit to the repo is from November 2024. It has 2.3 million downloads and over 200 open issues. So before we start with buckets and endpoints, just know that you’re putting a two year frozen plugin on your system. I covered the plugin briefly in my &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-across-all-your-devices-including-free-methods-1mi5"&gt;guide to syncing an Obsidian vault across devices&lt;/a&gt;. This is the long version of the part that guide skipped: pointing it at storage you own.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is Remotely Save Dead?&lt;/li&gt;
&lt;li&gt;Why Bring Your Own Bucket&lt;/li&gt;
&lt;li&gt;
What It Actually Costs

&lt;ul&gt;
&lt;li&gt;The AWS bill is mostly requests, not storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Setting Up Cloudflare R2&lt;/li&gt;
&lt;li&gt;Setting Up AWS S3 Without Handing Over Your Account&lt;/li&gt;
&lt;li&gt;The CORS Step You Can Skip&lt;/li&gt;
&lt;li&gt;WebDAV: Nextcloud, InfiniCLOUD, and Your NAS&lt;/li&gt;
&lt;li&gt;Encryption: RClone Crypt or OpenSSL&lt;/li&gt;
&lt;li&gt;Free vs. PRO, If You’re Picking a Backend Anyway&lt;/li&gt;
&lt;li&gt;Settings That Bite&lt;/li&gt;
&lt;li&gt;Should You Use It?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Is Remotely Save Dead?
&lt;/h2&gt;

&lt;p&gt;I don’t know, and neither does anybody else outside the developer’s head. This much is true as of this writing.&lt;/p&gt;

&lt;p&gt;The repo is not archived. No “this is dead now” posts. It installs from the community directory, and it still syncs my vault daily. Obsidian’s plugin API is not the type to break stuff often. So a 2024 plugin works… well… Mostly.&lt;/p&gt;

&lt;p&gt;What worries me more is not the code. It’s &lt;a href="https://remotelysave.com/" rel="noopener noreferrer"&gt;remotelysave.com&lt;/a&gt; that handles PRO tier. “FREE during beta until Jan 1, 2027”. “The price will be set later.” That’s 10 weeks from when this posts.&lt;/p&gt;

&lt;p&gt;Unreleased for 2 years plugin, service with a deadline, but no price. Not exactly confidence-inspiring.&lt;/p&gt;

&lt;p&gt;I wrote it anyway because &lt;strong&gt;it all runs on free tier below&lt;/strong&gt;. S3, Cloudflare R2, Backblaze B2, MinIO, WebDAV. No account needed at remotelysave.com.&lt;/p&gt;

&lt;p&gt;If PRO service disappeared tomorrow, you’re still good. The plugin communicates directly to your bucket. There is no intermediary server in the mix. If you’re going to use a zombie plugin, this is how you should do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Bring Your Own Bucket
&lt;/h2&gt;

&lt;p&gt;Obsidian Sync is the easy answer and it’s good. But the Standard plan gives you 1GB of storage.&lt;/p&gt;

&lt;p&gt;I measured the part of my writing vault that Remotely Save syncs: 9,371 files, 1.62GB. Only 80MB of that is markdown. The rest is images, PDFs, and the junk from years of web clipping. So Standard is already too small for me, and I’d be on Plus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fthqagpfsvskzdj070fnv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fthqagpfsvskzdj070fnv.jpg" alt="Why Bring Your Own Bucket" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The BYO storage pitch is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The storage is yours.&lt;/strong&gt; Your notes live in a bucket you own, in a format you can read without Obsidian.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s cheap or free.&lt;/strong&gt; For a normal vault, the bill rounds to zero. I’ll show numbers in a bit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works everywhere Obsidian does,&lt;/strong&gt; including iOS, where folder sync is a nightmare. I covered why in the &lt;a href="https://dev.to/eristoddle/how-to-sync-obsidian-on-iphone-and-ipad-for-free-in-2026-427p"&gt;iPhone and iPad sync guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Trade off is someone else’s problem becomes your problem. Obsidian Sync has a support team. You have your R2 bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Actually Costs
&lt;/h2&gt;

&lt;p&gt;I went through my own vault: 1.62GB, synced from 3 devices.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Backend&lt;/th&gt;
&lt;th&gt;Free allowance&lt;/th&gt;
&lt;th&gt;After that&lt;/th&gt;
&lt;th&gt;My 1.62GB vault&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloudflare R2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10GB storage, 1M Class A ops, 10M Class B ops per month&lt;/td&gt;
&lt;td&gt;$0.015/GB-month, zero egress&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backblaze B2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;First 10GB free, egress free up to 3x what you store&lt;/td&gt;
&lt;td&gt;$6.95/TB-month&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS S3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;New-account credits only&lt;/td&gt;
&lt;td&gt;about $0.023/GB-month, plus requests&lt;/td&gt;
&lt;td&gt;well under $1 a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MinIO, self-hosted&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Whatever disk you have&lt;/td&gt;
&lt;td&gt;Your electricity and your weekend&lt;/td&gt;
&lt;td&gt;$0 and a weekend&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;R2 is the sleeper pick. No egress fees from Cloudflare. All those devices that download your full vault for the first time, that’s egress. 10 free gigabytes is a lot of markdown.&lt;/p&gt;

&lt;h3&gt;
  
  
  The AWS bill is mostly requests, not storage
&lt;/h3&gt;

&lt;p&gt;AAWS is the weird numbers one. Storing 1.62GB in S3 Standard costs about four cents a month. No big deal.&lt;/p&gt;

&lt;p&gt;What costs money is asking the bucket what’s in it. A sync starts by listing the remote files, and S3 bills LIST requests at the same rate as PUT, $0.005 per thousand. A listing returns at most 1,000 objects, so my vault takes about 10 requests just to look. Run auto-sync every five minutes on three devices for eight hours a day and you’re at around 86,000 list requests a month. That’s roughly 43 cents. More than ten times the storage bill, for checking whether anything changed.&lt;/p&gt;

&lt;p&gt;Forty-three cents is still nothing. But it’s why people get surprised by S3 bills, and it’s one more reason R2’s flat free tier is the better deal for this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Cloudflare R2
&lt;/h2&gt;

&lt;p&gt;This is the setup I’d pick if I were starting today. Remotely Save’s own &lt;a href="https://github.com/remotely-save/remotely-save/blob/master/docs/remote_services/s3_cloudflare_r2/README.md" rel="noopener noreferrer"&gt;R2 tutorial&lt;/a&gt; is short, and so is this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcrdmj84hbd23pne9cyb0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcrdmj84hbd23pne9cyb0.jpg" alt="Setting Up Cloudflare R2" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make a Cloudflare account and enable R2.&lt;/strong&gt; It will probably want a credit card even though you’ll stay in the free tier. Annoying, but normal for cloud storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a bucket.&lt;/strong&gt; Name it something like &lt;code&gt;obsidian-vault&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create an API token&lt;/strong&gt; with &lt;strong&gt;Object Read &amp;amp; Write&lt;/strong&gt; permission, scoped to just that bucket. Don’t give it access to everything on your account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Save what it shows you:&lt;/strong&gt; the access key, the secret key, and the endpoint URL. Cloudflare only shows the secret once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In Obsidian&lt;/strong&gt; , install Remotely Save (the &lt;a href="https://dev.to/eristoddle/how-to-install-activate-and-update-obsidian-plugins-4d2p"&gt;plugin install walkthrough&lt;/a&gt; covers that), open its settings, and pick &lt;strong&gt;S3 or compatible&lt;/strong&gt; as the remote service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fill in&lt;/strong&gt; the endpoint, region &lt;code&gt;us-east-1&lt;/code&gt;, access key, secret key, and bucket name. R2 doesn’t really use regions, and &lt;code&gt;us-east-1&lt;/code&gt; is what the tutorial says to put there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn on Bypass CORS.&lt;/strong&gt; The tutorial calls this “usually what you want,” and it is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click Check Connectivity&lt;/strong&gt; , then run your first sync.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Back up the vault before that first sync. Copy the folder somewhere Remotely Save doesn’t know about. Every sync tool I’ve covered in this series gets the same advice, because the first sync is when you find out you configured something backwards.&lt;/p&gt;

&lt;p&gt;The one R2 issue: older versions of the plugin failed the connectivity check even when the settings were right, because Cloudflare doesn’t allow that kind of key to run &lt;code&gt;HeadBucket&lt;/code&gt;. Version 0.3.29 switched to &lt;code&gt;ListObjects&lt;/code&gt; and fixed it. Since the current version is 0.5.25, this only bites you if you’re running something ancient. If the check fails, look at your keys before you blame Cloudflare.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up AWS S3 Without Handing Over Your Account
&lt;/h2&gt;

&lt;p&gt;R2 asks for a scoped token and you’re done. AWS makes you build the scope yourself, and this is where it’s easy to get stuck. The easy move is to use your root account’s keys because they’re right there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t.&lt;/strong&gt; Those keys can do anything to your entire AWS account, and now they live in a plugin settings file on your phone.&lt;/p&gt;

&lt;p&gt;Instead, create an IAM policy that can touch one bucket and nothing else. This is the policy from the plugin’s &lt;a href="https://github.com/remotely-save/remotely-save/blob/master/docs/remote_services/s3_general/s3_user_policy.md" rel="noopener noreferrer"&gt;S3 user policy doc&lt;/a&gt;, with &lt;code&gt;my-bucket&lt;/code&gt; swapped for your bucket name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ObsidianObjects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:HeadObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListBucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:CopyObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:UploadPart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:UploadPartCopy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListMultipartUploads"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:AbortMultipartUpload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:CompleteMultipartUpload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListObjects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListObjectsV2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListParts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObjectAttributes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:DeleteObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:DeleteObjects"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bucket/*"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In IAM, create a new user and choose &lt;strong&gt;Attach policies directly&lt;/strong&gt;. Attach the policy above.&lt;/li&gt;
&lt;li&gt;Open that user, go to &lt;strong&gt;Security credentials&lt;/strong&gt; , and create an access key. If it asks for a use case, pick &lt;strong&gt;Other&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Put that access key, the secret, your bucket name, and the bucket’s region into Remotely Save.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The doc says that the bucket itself doesn’t need a policy, only the user. It also says “not fully tested,” which is good of them to admit, and a reason to test a sync with a throwaway note first.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CORS Step You Can Skip
&lt;/h2&gt;

&lt;p&gt;If you’ve read an older Remotely Save guide, you’ve seen a big block of CORS JSON with origins like &lt;code&gt;app://obsidian.md&lt;/code&gt; and &lt;code&gt;capacitor://localhost&lt;/code&gt;. It used to be the step that broke everybody’s setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvj32v8v6kib8cbr017ex.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvj32v8v6kib8cbr017ex.jpg" alt="The CORS Step You Can Skip" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You probably don’t need it anymore. The plugin’s &lt;a href="https://github.com/remotely-save/remotely-save/blob/master/docs/remote_services/s3_general/s3_cors_configure.md" rel="noopener noreferrer"&gt;CORS doc&lt;/a&gt; says it’s only required on Obsidian desktop below 0.13.25 or mobile below 1.1.1. Newer Obsidian lets the plugin make requests that don’t go through the browser’s CORS rules, which is what the Bypass CORS toggle is about. Those version numbers are years old. If you are running Obsidian that old, CORS is not your biggest problem.&lt;/p&gt;

&lt;p&gt;So if a tutorial sends you into your bucket’s CORS settings, skip it, turn on Bypass CORS, and only come back to it if the connectivity check fails. WebDAV has its own CORS doc with the same desktop and iOS cutoffs, plus one exception: it says Android needs CORS on the WebDAV server at any version, and Nextcloud and ownCloud don’t turn it on by default. If you sync from an Android phone over WebDAV, read that doc before you skip anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebDAV: Nextcloud, InfiniCLOUD, and Your NAS
&lt;/h2&gt;

&lt;p&gt;WebDAV is the other free-tier backend, and it’s the one for people who already run a server or own a NAS. Remotely Save has setup docs for a dozen of them. Here’s the 3 most people will care about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nextcloud.&lt;/strong&gt; If you already self-host it, this is the obvious pick. Your notes land next to everything else you run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synology NAS.&lt;/strong&gt; Turn on the WebDAV Server package and point the plugin at it. It’s great at home. Away from home you’ll need a way to reach the NAS, and exposing it to the internet so your phone can sync is something to do only if you understand what you’re letting in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;InfiniCLOUD&lt;/strong&gt; (it used to be called TeraCLOUD). A hosted WebDAV service with a free plan that recent listings put at 20GB. The catch is that free accounts can be deleted after two years without a login. A sync plugin that’s working perfectly never makes you log into the website, so put a reminder in your calendar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setup is the same every time: pick &lt;strong&gt;Webdav&lt;/strong&gt; in the plugin, enter the server address, username, and password, and check connectivity. The plugin puts your vault in a subfolder named after it, so one WebDAV account can hold several vaults without them stepping on each other.&lt;/p&gt;

&lt;p&gt;I’ve never run my vault through WebDAV. I’ve used Dropbox the whole time. So for this section I’m going on the plugin’s docs, not my scars. If you hit something weird with a specific server, the per-server tutorials in the repo’s &lt;code&gt;docs/remote_services/&lt;/code&gt; folder are where to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encryption: RClone Crypt or OpenSSL
&lt;/h2&gt;

&lt;p&gt;If you set a password, Remotely Save encrypts your files on your device before they go up. Leave it blank and your notes sit in the bucket as plain markdown. With your own S3 bucket, plain is defensible. With a third-party WebDAV host, set a password.&lt;/p&gt;

&lt;p&gt;You get two formats, and the plugin recommends RClone Crypt. Its own &lt;a href="https://github.com/remotely-save/remotely-save/blob/master/docs/encryption/comparation.md" rel="noopener noreferrer"&gt;comparison page&lt;/a&gt; lays out the difference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0a8c6xjnx05bdzxgwm4g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0a8c6xjnx05bdzxgwm4g.jpg" alt="Encryption: RClone Crypt or OpenSSL" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;RClone Crypt (recommended)&lt;/th&gt;
&lt;th&gt;OpenSSL enc&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;XSalsa20Poly1305, in chunks&lt;/td&gt;
&lt;td&gt;AES-256-CBC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Filenames&lt;/td&gt;
&lt;td&gt;Each path segment encrypted separately&lt;/td&gt;
&lt;td&gt;The whole path encrypted as one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reading it without Obsidian&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rclone&lt;/code&gt; can mount the bucket decrypted&lt;/td&gt;
&lt;td&gt;Write your own script&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The filename row is the real tradeoff. RClone Crypt encrypts each folder name and filename on its own, so your folder structure survives. Someone with access to the bucket can’t read your note titles, but they can see that you have a folder with 400 things in it, nested three deep. OpenSSL hides the structure too, at the cost of not being able to open your vault with a standard tool.&lt;/p&gt;

&lt;p&gt;I’d still take RClone Crypt. Being able to run &lt;code&gt;rclone mount&lt;/code&gt; and read my notes without Obsidian is the point of owning the bucket.&lt;/p&gt;

&lt;p&gt;Two warnings from that page. First, if you ever switch formats, you have to delete the remote files “manually and fully” so the plugin can re-upload everything. Second, the page says the author “doesn’t have sufficient knowledge to ‘judge’ which one is the better format.” Credit for saying so, and a reminder that this is a hobby project’s encryption, not an audited product. Use a long password. Also, for Dropbox, OneDrive, and WebDAV, the vault’s name itself isn’t encrypted. Don’t name your vault after something you’re hiding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free vs. PRO, If You’re Picking a Backend Anyway
&lt;/h2&gt;

&lt;p&gt;The split as of 0.5.x:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free, no account:&lt;/strong&gt; S3 and anything S3-compatible (R2, B2, MinIO), Dropbox, WebDAV, OneDrive’s App Folder, and Webdis, which the README calls “mostly experimental.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRO, needs a remotelysave.com account:&lt;/strong&gt; Google Drive, Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage, full OneDrive access, and Smart Conflict.&lt;/p&gt;

&lt;p&gt;Smart Conflict is the PRO feature I’d actually miss. On the free tier, the plugin detects a conflict and you pick a rule: keep the newer file or keep the larger one. Whichever loses is gone. Smart Conflict tries to merge two versions of a small markdown file instead, and for anything it can’t merge, it keeps both.&lt;/p&gt;

&lt;p&gt;The free list is exactly the backends this post is about. If you choose R2, B2, S3, or WebDAV, the PRO price that gets announced after January 1 doesn’t touch you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Settings That Bite
&lt;/h2&gt;

&lt;p&gt;Most of these come from the README, which I read properly for the first time while writing this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffpitp62rr6ph7j5ysy6b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffpitp62rr6ph7j5ysy6b.jpg" alt="The Settings That Bite" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Files starting with &lt;code&gt;.&lt;/code&gt; or &lt;code&gt;_&lt;/code&gt; don’t sync by default.&lt;/strong&gt; If you have an &lt;code&gt;_attachments&lt;/code&gt; folder, it isn’t going anywhere. Your &lt;code&gt;.obsidian&lt;/code&gt; config folder can sync, but that option is marked experimental.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-sync only runs while Obsidian is open.&lt;/strong&gt; It’s an interval timer inside the app. Close the app and nothing syncs. Open it on your phone and nothing is current until the next run, so hit sync by hand before you start writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors “fail silently.”&lt;/strong&gt; That’s the README’s phrase. A broken auto-sync looks exactly like a working one with nothing to sync. Check the last sync time once in a while.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Big files are slow on mobile.&lt;/strong&gt; The README flags trouble at 50MB and up. There’s a Skip Large Files setting and a regex filter for paths. Use them before your phone tries to pull down a 300MB PDF over cell data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;data.json&lt;/code&gt; holds your keys.&lt;/strong&gt; It’s in &lt;code&gt;.obsidian/plugins/remotely-save/&lt;/code&gt;, and it has your secret key or tokens in it. The plugin drops a &lt;code&gt;.gitignore&lt;/code&gt; into its own folder that excludes it. And one I did to myself. My laptops sync the vault through the Dropbox app, and my mobile devices sync it through Remotely Save. That plugin folder sits inside the vault, so Dropbox syncs each laptop’s copy of the plugin’s settings file. When I went looking just now, I found this in it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(Stephan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Miller's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;conflicted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2025-12-14&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(Stephan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Miller's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;conflicted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2025-12-14&lt;/span&gt;&lt;span class="err"&gt;).json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A conflicted copy of a conflicted copy. That’s my own rule from the pillar, “don’t run two sync systems on one vault,” broken by me in my own vault, and it’s been there since December. It’s harmless here, since the plugin ignores those files. But it’s the kind of mess you get when two tools both think they’re in charge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Use It?
&lt;/h2&gt;

&lt;p&gt;If you want Obsidian on every device without a subscription, and you’re fine owning a bucket, yes. With a caveat I didn’t have to write a year ago.&lt;/p&gt;

&lt;p&gt;Remotely Save has done its job for my phone and iPad for years and it’s still doing it today. R2 makes it free for most vaults. AWS makes it cost pocket change, mostly for listing files. WebDAV is free if you already run the server. Encryption is there, with the author’s own disclaimer attached.&lt;/p&gt;

&lt;p&gt;But it hasn’t had a release since October 2024, and nobody is telling us whether that’s a pause or the end. So set it up the way that survives the plugin going away: a free-tier backend, RClone Crypt if you encrypt, and a backup that isn’t the sync target. If the plugin stops working someday, your notes are still in a bucket you own, readable with &lt;code&gt;rclone&lt;/code&gt;. That’s a better exit than most sync tools give you.&lt;/p&gt;

&lt;p&gt;If you’d rather someone else worry about all this, &lt;a href="https://dev.to/eristoddle/obsidian-dropbox-sync-a-setup-guide-2ajl"&gt;Dropbox&lt;/a&gt; is the simplest Remotely Save backend, and &lt;a href="https://dev.to/eristoddle/syncthing-for-obsidian-free-private-and-genuinely-annoying-3dbm"&gt;Syncthing&lt;/a&gt; skips the cloud entirely. Me, I’m keeping my setup. I should probably delete that conflicted copy, too.&lt;/p&gt;

</description>
      <category>obsidian</category>
    </item>
    <item>
      <title>Gemini 4 Argon Is for Sale Now. The Price Doubles December 1.</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Tue, 20 Oct 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/gemini-4-argon-is-for-sale-now-the-price-doubles-december-1-4a4c</link>
      <guid>https://dev.to/eristoddle/gemini-4-argon-is-for-sale-now-the-price-doubles-december-1-4a4c</guid>
      <description>&lt;p&gt;For two issues in a row I printed a second cheapskate table, because the model at the top of the first one wasn’t for sale. Gemini 4 Argon sat at number one in every Arena category, and you couldn’t buy it unless Google had vetted you as a cyber defender for its Fairwind program.&lt;/p&gt;

&lt;p&gt;You can buy it now. Google made it generally available on October 13, and OpenRouter listed it the same day. So I deleted the second table. Then I went to see what the first wave of paying customers had to say, and the top thread on r/GeminiAI is titled “Out of Gemini 4 Argon usage after 10 messages.” You know how that goes.&lt;/p&gt;

&lt;p&gt;Argon wasn’t the only thing going on. DeepSeek pushed a “minor update” to its Flash model on Friday, and by Sunday it was the busiest model on OpenRouter. Meta, which went closed back in April, put out open weights again. Reflection shipped a 501B open model with a benchmark claim that the independent numbers don’t back up. StepFun’s weights showed up after all. And somebody broke into OpenCode Console and spent people’s API credits for them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Gemini 4 Argon went on sale, and the first complaint was the limits

&lt;ul&gt;
&lt;li&gt;What the paying customers said&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
DeepSeek shipped a “minor update” and took the daily top spot

&lt;ul&gt;
&lt;li&gt;The price depends on what time it is&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Open weights week

&lt;ul&gt;
&lt;li&gt;Meta went back to open, sort of&lt;/li&gt;
&lt;li&gt;Reflection Beam 1.0: big claim, small index&lt;/li&gt;
&lt;li&gt;Step 5’s weights showed up, and the free traffic left&lt;/li&gt;
&lt;li&gt;Space Bunny got a name&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The cheapskate table: one table again

&lt;ul&gt;
&lt;li&gt;GLM-5.3-Flash missed Overall by six hundredths of a point&lt;/li&gt;
&lt;li&gt;The rest of the table&lt;/li&gt;
&lt;li&gt;Speed is still the catch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Local sweet spot&lt;/li&gt;
&lt;li&gt;
Horror stories

&lt;ul&gt;
&lt;li&gt;OpenCode Console leaked people’s API keys&lt;/li&gt;
&lt;li&gt;The Argon usage wall&lt;/li&gt;
&lt;li&gt;The peak-hour batch job&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What’s coming&lt;/li&gt;
&lt;li&gt;Finally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gemini 4 Argon went on sale, and the first complaint was the limits
&lt;/h2&gt;

&lt;p&gt;As of October 13, Argon is &lt;a href="https://pasqualepillitteri.it/en/news/23457/gemini-4-argon-disponibile-dove-usarlo-prezzo-en" rel="noopener noreferrer"&gt;generally available&lt;/a&gt; in the Gemini API on the paid plan (the model string is &lt;code&gt;gemini-4-argon&lt;/code&gt;), in the Gemini app for AI Pro and Ultra subscribers, and in AI Studio and Antigravity for Ultra. The Fairwind-only restriction is gone for paying customers. On &lt;a href="https://openrouter.ai/google/gemini-4-argon" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt; it’s $2 in and $10 out, with a flex tier at $1/$5 if you can wait.&lt;/p&gt;

&lt;p&gt;That $2/$10 is still the intro price. It has an end date now: &lt;a href="https://andrew.ooo/answers/gemini-4-argon-generally-available-price-access-limits-october-2026/" rel="noopener noreferrer"&gt;$4/$20 from December 1&lt;/a&gt;. So if you build a budget on Argon this month, build it on the December number.&lt;/p&gt;

&lt;p&gt;So is it worth $10 a million? Arena still has it number one Overall (1524, now on 4,904 votes), plus Coding, Instruction Following, Hard Prompts, and Math. But it lost one. Claude Opus 5.5 took Creative Writing, 1519 to 1516. That’s three and a half points, which is nothing statistically, but it’s the first category Argon hasn’t swept since it showed up. And the Math lead is sitting on 273 votes, so I wouldn’t tattoo that one anywhere.&lt;/p&gt;

&lt;p&gt;Artificial Analysis likes it less. Argon scores 53 on the &lt;a href="https://artificialanalysis.ai/leaderboards/models" rel="noopener noreferrer"&gt;Intelligence Index&lt;/a&gt;, tied with GPT-6 Astra and behind Opus 5.5 (58), Sonnet 5.5 (56), and Meta’s Muse Wonder Full (56). That’s the same split I’ve been writing about for weeks: Arena voters love it, the hard benchmarks say it’s frontier but not the top of the frontier.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the paying customers said
&lt;/h3&gt;

&lt;p&gt;Reddit was reachable this week, so I got real threads instead of aggregator summaries. The loudest ones are about the consumer apps, not the API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://www.reddit.com/r/GeminiAI/comments/1x5nyfu/out_of_gemini_4_argon_usage_after_10_messages/" rel="noopener noreferrer"&gt;r/GeminiAI usage thread&lt;/a&gt; I mentioned up top has 733 points and 141 comments. The top comment’s theory is that Argon is just very expensive for Google to run, and the limits are how Google pays for it.&lt;/li&gt;
&lt;li&gt;On r/AntigravityGoogle: “&lt;a href="https://www.reddit.com/r/AntigravityGoogle/comments/1x79jlx/to_all_the_pro_users_thinking_of_upgrading_to/" rel="noopener noreferrer"&gt;To all the Pro users thinking of upgrading to Ultra for Gemini 4 Argon: Don’t do it. The limits are a joke.&lt;/a&gt;” (430 points). Another thread there, “&lt;a href="https://www.reddit.com/r/AntigravityGoogle/comments/1x54fqo/gemini_4_argon_did_way_more_damage_than_good/" rel="noopener noreferrer"&gt;Gemini 4 Argon did way more damage than good&lt;/a&gt;” (794 points), has at least one person saying the botched release made them cancel.&lt;/li&gt;
&lt;li&gt;The positive one is from launch week. An r/singularity thread called “&lt;a href="https://www.reddit.com/r/singularity/comments/1wuj72j/gemini_4_argon_solved_hallucinations/" rel="noopener noreferrer"&gt;Gemini 4 Argon solved hallucinations&lt;/a&gt;” got 1,608 points, and the top reply sums it up: “‘solved’ 15% But yeah, it’s a very nice improvement if not benchmaxxed.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want Argon, I’d use the API and pay per token, where you know what you’re getting. Paying for an Ultra subscription to get Argon in the app is the move people are warning each other off of.&lt;/p&gt;

&lt;h2&gt;
  
  
  DeepSeek shipped a “minor update” and took the daily top spot
&lt;/h2&gt;

&lt;p&gt;On October 17, DeepSeek put out &lt;a href="https://openrouter.ai/deepseek/deepseek-v4.1-flash-1017" rel="noopener noreferrer"&gt;DeepSeek V4.1 Flash 1017&lt;/a&gt;, a new snapshot of the model that was already number one on OpenRouter. It now sits behind DeepSeek’s &lt;code&gt;deepseek-flash&lt;/code&gt; API name, and the &lt;a href="https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash-1017" rel="noopener noreferrer"&gt;weights went up on Hugging Face&lt;/a&gt; under MIT the same day.&lt;/p&gt;

&lt;p&gt;Two days later it had the top spot on &lt;a href="https://openrouter.ai/rankings" rel="noopener noreferrer"&gt;OpenRouter’s&lt;/a&gt; daily board. The board through October 19 has it at 3.61 trillion tokens for the day, first place, with the original V4.1 Flash second at 2.8 trillion. For the week it’s sixth at 7.34 trillion on about two days of traffic, and first on New &amp;amp; Trending. The original V4.1 Flash is still number one for the week (29.6 trillion), but it’s down 27 percent, so you can watch the traffic move from one to the other. DeepSeek is now 24.4 percent of every request on OpenRouter.&lt;/p&gt;

&lt;p&gt;Artificial Analysis gives the 1017 snapshot a &lt;a href="https://artificialanalysis.ai/models/deepseek-v4-1-flash-1017" rel="noopener noreferrer"&gt;45&lt;/a&gt;, second among the 121 open-weights models it tracks (MiMo-V2.6-Pro is first at 46). AA clocks it at 211 tokens a second, with the first token arriving in about a second. The catch is the same one I keep finding with the smart cheap models. It took 210 million output tokens to get through AA’s index, against a median of 140 million, and AA doesn’t put it on the intelligence-versus-cost frontier.&lt;/p&gt;

&lt;p&gt;r/LocalLLaMA’s &lt;a href="https://www.reddit.com/r/LocalLLaMA/comments/1x84po4/deepseekaideepseekv41flash1017_hugging_face/" rel="noopener noreferrer"&gt;release thread&lt;/a&gt; has 1,117 points and 314 comments. The top comment (605 upvotes): “‘minor update’ Proceeds to obliterate GLM5.3, Kimi K3 and GPT5.6 Sol.” Another one notes that “Flash is now 700B,” which is about right going by the size of the safetensors on Hugging Face. And a 519-upvote reply warns that one of the charts going around comes from a knockoff benchmark site dressed up to look like Artificial Analysis. Check where a chart comes from before you share it.&lt;/p&gt;

&lt;p&gt;Over on r/DeepSeek, someone ran &lt;a href="https://www.reddit.com/r/DeepSeek/comments/1x8kwp7/deepseek_v41_flash_1017_vs_claude_opus_55_same/" rel="noopener noreferrer"&gt;1017 against Claude Opus 5.5&lt;/a&gt; on the same task. The top reply had the most sensible take of the week: priced like Haiku, performs closer to Sonnet than Opus. And r/opencode noticed &lt;a href="https://www.reddit.com/r/opencode/comments/1x6fj9m/deepseek_v41_flash_is_free_in_opencode/" rel="noopener noreferrer"&gt;it’s free in OpenCode&lt;/a&gt; (1,666 points), where the replies went straight to “you are the product” and complaints about the 200K context cap.&lt;/p&gt;

&lt;h3&gt;
  
  
  The price depends on what time it is
&lt;/h3&gt;

&lt;p&gt;DeepSeek’s own endpoint charges $0.15 in and $0.60 out off-peak. During peak hours it’s &lt;a href="https://www.eesel.ai/blog/deepseek-v4-1-flash-pricing" rel="noopener noreferrer"&gt;exactly double&lt;/a&gt;, $0.30/$1.20. Peak is 01:00 to 04:00 and 06:00 to 10:00 UTC, Monday through Friday. That’s Beijing’s working day. In US Central time, while daylight saving lasts, that’s 8 to 11pm and 1 to 5am.&lt;/p&gt;

&lt;p&gt;DeepSeek didn’t invent this for 1017. It’s been charging by the clock since V4.1 launched in September. But now that millions of requests a day are moving onto it, the gap costs real money. “60 cents” is the number everybody quotes and $1.20 is the number you pay if your overnight batch job runs at the wrong damn time. In my cheapskate math I use the $1.20, since that’s the rate you can’t schedule your way out of.&lt;/p&gt;

&lt;p&gt;It’s not on Arena yet, so it doesn’t get a row in the table this week. The older V4.1 Flash is in the Overall band at 38th place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open weights week
&lt;/h2&gt;

&lt;p&gt;Three labs put out big open-weight models in the same week, and a fourth confirmed a stealth model’s identity. None of them change the cheapskate table yet. One of them is Meta reversing itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Meta went back to open, sort of
&lt;/h3&gt;

&lt;p&gt;Back in April, one of my first roundups led with Meta abandoning open source for Muse Spark. On October 15 Meta released &lt;a href="https://pasqualepillitteri.it/en/news/24330/meta-muse-spark-open-816b-open-weights" rel="noopener noreferrer"&gt;Muse Spark Open&lt;/a&gt;, with weights on Hugging Face, SageMaker, Vertex Model Garden, and Microsoft Foundry. It’s 816 billion parameters with 42 billion active, a 1M context window, native image and video input, and it’s built for coding and agent work.&lt;/p&gt;

&lt;p&gt;The license is the first problem. It ships under the Muse Model License, which has &lt;a href="https://www.trendingtopics.eu/muse-spark-open-meta-open-weight-license/" rel="noopener noreferrer"&gt;commercial limits&lt;/a&gt;, so you can download the weights and still not be allowed to do whatever you want with them. If you’re building a product on it, have somebody read that license before you write any code.&lt;/p&gt;

&lt;p&gt;And you aren’t running this at home. The &lt;a href="https://www.yottalabs.ai/post/muse-spark-open-hardware-requirements-gpu-memory" rel="noopener noreferrer"&gt;hardware floor&lt;/a&gt; is about 700GB of VRAM at NVFP4 (four Blackwell Ultras or eight H200s) and about 2TB at BF16. On Artificial Analysis it scores 39, behind Kimi K3 and GLM 5.3 according to &lt;a href="https://www.developersdigest.tech/blog/muse-spark-open-weights-816b-run-it-2026" rel="noopener noreferrer"&gt;Developers Digest&lt;/a&gt;. Meta hosts it on OpenRouter at $1.25/$4.25. Why pay $4.25 out for a 39 when DeepSeek’s snapshot scores 45 and tops out at $1.20?&lt;/p&gt;

&lt;p&gt;I’ll still take it. Six months ago the story was Meta closing the door, and this week I could pull Muse weights off Hugging Face (if I had a rack of H200s to put them on).&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflection Beam 1.0: big claim, small index
&lt;/h3&gt;

&lt;p&gt;Reflection AI, the NVIDIA-backed startup from former DeepMind researchers, released &lt;a href="https://www.vktr.com/ai-platforms/reflection-ai-unveils-beam-a-501b-open-weight-model/" rel="noopener noreferrer"&gt;Beam 1.0&lt;/a&gt; on October 16. It’s 501B total and 23B active, under &lt;a href="https://techjacksolutions.com/ai-brief/reflection-ai-beam-501b-weights-live-apache-download/" rel="noopener noreferrer"&gt;Apache 2.0&lt;/a&gt;, which is a real open license this time. OpenRouter has it at $0.30/$1.00.&lt;/p&gt;

&lt;p&gt;Reflection says it scores 80.9 percent on SWE-bench Verified and is three to four times more efficient than GLM 5.2. Artificial Analysis, which averages a much broader set of hard evals, gives it a 30. It’s fast (AA clocks about 350 tokens a second), but a 30 sits a long way below what that SWE-bench number implies. This is the same vendor-table problem I flagged with Meta’s Muse Wonder last week. The lab’s chart says one thing, the independent average says another, and when they’re this far apart I go with the independent one until someone explains the gap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5’s weights showed up, and the free traffic left
&lt;/h3&gt;

&lt;p&gt;Last week I said I wouldn’t count StepFun’s promised October 15 weights as shipped until there was something on Hugging Face. There is. &lt;a href="https://huggingface.co/stepfun-ai/Step-5-Preview" rel="noopener noreferrer"&gt;stepfun-ai/Step-5-Preview&lt;/a&gt; went up on the 15th, with BF16 and NVFP4 variants, though early that morning &lt;a href="https://www.orcarouter.ai/fr/blog/step-5-preview-open-weights" rel="noopener noreferrer"&gt;people were reporting a 404&lt;/a&gt;. The license field says “other,” so read it before you use it.&lt;/p&gt;

&lt;p&gt;I also said to watch what happened to Step 5’s traffic once the free week ended on October 16. It fell 32 percent to 8.22 trillion tokens, and it’s still fourth on OpenRouter for the week. I figured the freeloaders would bail harder than that. About a third of the traffic left, and I’d guess most of the rest is paying $2.70 out now. Arena still has it 84th Overall. In Coding it’s 63rd, missing the 50-point band by 1.3 points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Space Bunny got a name
&lt;/h3&gt;

&lt;p&gt;The free stealth model that was number one on OpenRouter three weeks ago has an identity. According to &lt;a href="https://www.eesel.ai/blog/minimax-m3-1-flash" rel="noopener noreferrer"&gt;eesel&lt;/a&gt;, Space Bunny Alpha was MiniMax M3.1, which is what everybody guessed. MiniMax M3.1 Flash showed up on OpenRouter as a free model on October 19 and did 1.05 trillion tokens on its first day, seventh place. AA gives it 43 at about 105 tokens a second.&lt;/p&gt;

&lt;p&gt;There are no Hugging Face weights yet, and no model card or technical report either. You can’t turn thinking off, only turn it down, and it defaults to max effort. And outside the free OpenRouter endpoint, eesel says MiniMax currently sells it through subscription plans at $20, $50, or $120 a month rather than a published per-token price. Free endpoints on OpenRouter have a habit of turning into paid ones with about a week’s notice, so I’ll check on this one next issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheapskate table: one table again
&lt;/h2&gt;

&lt;p&gt;If you’re new here: for each Arena category I take the leader’s rating, subtract 50, and look for the cheapest model still above that line. The band gets computed in code from every row on the board, and I write down the first model below the line so I know nothing got cut off. The board comes from &lt;a href="https://huggingface.co/datasets/lmarena-ai/leaderboard-dataset" rel="noopener noreferrer"&gt;LMArena’s leaderboard dataset&lt;/a&gt; on Hugging Face (arena.ai’s site still blocks me), published October 15. Prices are each maker’s own endpoint on OpenRouter.&lt;/p&gt;

&lt;p&gt;Since Argon is for sale now, there’s only one table. Argon is priced at its $10 intro rate.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Leader&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Cheapskate pick&lt;/th&gt;
&lt;th&gt;$ out&lt;/th&gt;
&lt;th&gt;Δ rating&lt;/th&gt;
&lt;th&gt;Cheaper by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1524)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Pro (1479, #27)&lt;/td&gt;
&lt;td&gt;$0.87&lt;/td&gt;
&lt;td&gt;−45&lt;/td&gt;
&lt;td&gt;11.5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1559)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;MiMo-V2.6-Flash* (1513, #51)&lt;/td&gt;
&lt;td&gt;$0.28&lt;/td&gt;
&lt;td&gt;−46&lt;/td&gt;
&lt;td&gt;36×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Creative Writing&lt;/td&gt;
&lt;td&gt;claude-opus-5.5-high (1519)&lt;/td&gt;
&lt;td&gt;$20&lt;/td&gt;
&lt;td&gt;gemini-3.7-flash-high (1491, #5)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−28&lt;/td&gt;
&lt;td&gt;5.3×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction Following&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1527)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;gemini-3.8-flash-high (1490, #14)&lt;/td&gt;
&lt;td&gt;$3.75&lt;/td&gt;
&lt;td&gt;−37&lt;/td&gt;
&lt;td&gt;2.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hard Prompts&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1549)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1500, #34)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−49&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Math&lt;/td&gt;
&lt;td&gt;gemini-4-argon-high (1529)&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash (1506, #8)&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;−23&lt;/td&gt;
&lt;td&gt;20×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*2,625 votes, 3.6 points above the cutoff. GLM-5.3-Flash sits at 1525 with 8,457 votes for 50 cents and is still the safer bet.&lt;/p&gt;

&lt;p&gt;Band depths: Overall 40, Coding 59, Creative 17, Instruction Following 23, Hard Prompts 35, Math 38.&lt;/p&gt;

&lt;h3&gt;
  
  
  GLM-5.3-Flash missed Overall by six hundredths of a point
&lt;/h3&gt;

&lt;p&gt;The Overall cutoff is 1473.90. The first model below it is GLM-5.3-Flash at 1473.84. That’s 0.06 points, out of a scale that runs to 1524. If it had made it, it would be the Overall pick at 50 cents and a 20x ratio. Instead the pick is MiMo-V2.6-Pro at 87 cents, for the third issue running.&lt;/p&gt;

&lt;p&gt;And GLM pushed 11.9 trillion tokens through OpenRouter this week, second only to DeepSeek. Plenty of people clearly think it’s good enough for general work, and my table leaves it out of Overall over a gap that disappears when you round to whole numbers. I don’t round, though. 1473.84 is under 1473.90, so GLM sits this one out.&lt;/p&gt;

&lt;p&gt;It went the other way in Hard Prompts. Last week GLM missed that band by 0.3. This week it’s in by 1.0, on 20,935 votes, and it’s the pick at 20x. It also holds Math for the third issue in a row, 8th place on that board.&lt;/p&gt;

&lt;h3&gt;
  
  
  The rest of the table
&lt;/h3&gt;

&lt;p&gt;Opus 5.5 beat Argon in Creative Writing, so that ratio now runs against Opus’s $20 instead of Argon’s $10, and Gemini 3.7 Flash stays the pick at 5.3x. Not one open model made that 17-model band. Instruction Following looks the same: the cheapest thing in its band is Gemini 3.8 Flash at $3.75. If you write fiction or need strict instruction following, you’re still paying for quality.&lt;/p&gt;

&lt;p&gt;MiMo-V2.6-Flash holds Coding for the third week, and it went up this time, 1,989 votes to 2,625. It’s still only 3.6 points over the line. My rule was that if it held the spot on a few thousand votes I’d call it the Coding pick for real. It’s getting there. I’d still run GLM-5.3-Flash for anything I cared about.&lt;/p&gt;

&lt;p&gt;Mark December 1 on the calendar, because every ratio with Argon as the leader doubles that day. Overall goes from 11.5x to 23x, and Hard Prompts and Math go from 20x to 40x, without a single pick changing. Google raises its price and the cheap models start looking twice as good.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed is still the catch
&lt;/h3&gt;

&lt;p&gt;The cheap end of the table is still slow. MiMo-V2.6-Pro, the best open model on AA at 46, runs at about &lt;a href="https://artificialanalysis.ai/models/mimo-v2-6-pro" rel="noopener noreferrer"&gt;50 tokens a second&lt;/a&gt;. MiMo-V2.6-Flash is around 54 and GLM-5.3-Flash about 78 this week (it moves around every week, so I re-pull it). Say your agent runs 20 steps and writes 1,000 tokens at each one. At 50 tokens a second that’s almost seven minutes of waiting. At the 211 that DeepSeek’s 1017 snapshot manages, it’s about a minute and a half, which is why I want to see where it lands once Arena rates it.&lt;/p&gt;

&lt;p&gt;The distillation accusation Anthropic made against Xiaomi in September still hangs over the MiMo family. Anthropic made that claim as a competitor, and nobody has ruled on it. If your contracts care where a model’s training data came from, factor it in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local sweet spot
&lt;/h2&gt;

&lt;p&gt;This section picks the biggest model that fits your machine with room left for context and still runs at 15 or more tokens a second. Nothing changed this week. I added Gemma 4 26B-A4B to the candidates and it didn’t beat Qwen3.8 27B on any tier. Every big open release this week (Muse Spark Open, Beam, the DeepSeek snapshot) is far too big for a 64GB machine.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your machine&lt;/th&gt;
&lt;th&gt;Pick&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Arena&lt;/th&gt;
&lt;th&gt;AA&lt;/th&gt;
&lt;th&gt;Measured tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mac 16GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;27 (n=4, 6-82)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 32GB&lt;/td&gt;
&lt;td&gt;qwen3.8-27b MLX 4bit&lt;/td&gt;
&lt;td&gt;16.1 GB&lt;/td&gt;
&lt;td&gt;1438 (#100)&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac 64GB+&lt;/td&gt;
&lt;td&gt;qwen3.8-27b MLX 8bit&lt;/td&gt;
&lt;td&gt;29.5 GB&lt;/td&gt;
&lt;td&gt;1438 (#100)&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;19 (n=1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 12GB&lt;/td&gt;
&lt;td&gt;qwen3.5-9b Q4_K_M&lt;/td&gt;
&lt;td&gt;5.7 GB&lt;/td&gt;
&lt;td&gt;unlisted&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;50 (n=1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA 24GB&lt;/td&gt;
&lt;td&gt;qwen3.8-27b Q4_K_M&lt;/td&gt;
&lt;td&gt;16.5 GB&lt;/td&gt;
&lt;td&gt;1438 (#100)&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;41 (n=2, 40-42)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 9B rows have no Arena rating, so they’re picked by what fits, not by a leaderboard. The Mac 32GB speed is still unmeasured. I’m not going to fill it in from a calculator site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Horror stories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  OpenCode Console leaked people’s API keys
&lt;/h3&gt;

&lt;p&gt;Overnight on October 18, attackers got into OpenCode Console, an older part of OpenCode’s online platform where some users store the API keys they use with OpenAI, Anthropic, and Google. &lt;a href="https://techcrunch.com/2026/10/19/hackers-hit-ai-coding-tool-opencode-running-up-charges-on-users-ai-accounts/" rel="noopener noreferrer"&gt;TechCrunch reports&lt;/a&gt; that 1.4 percent of Console users got breach notices, and people reported unauthorized charges from a few hundred dollars to more than $1,000. One user: “I saw my Open AI, Anthropic, and Google AI spend alerts all fire off before going to bed.” Some had their Google Cloud projects suspended on top of that, so they lost the money and the projects in the same night.&lt;/p&gt;

&lt;p&gt;Anthropic and Google blocked the exposed keys. OpenAI worked with OpenCode on refunds, and OpenCode says it’s refunding the charges too. Co-founder Dax Raad drew the line clearly: “Note this is the OpenCode Console, not OpenCode itself, those keys never come to us.” So the CLI didn’t leak anything. The web console did. OpenCode blamed a “large-scale distillation attack,” and &lt;a href="https://www.bleepingcomputer.com/news/security/opencode-hack-exposes-api-keys-amid-ai-distillation-attacks/" rel="noopener noreferrer"&gt;some security people&lt;/a&gt; said that hasn’t been proven.&lt;/p&gt;

&lt;p&gt;If you ever pasted a provider key into OpenCode Console, rotate it at the provider today. And set spend alerts on every provider account you have. Those alerts are the only reason the guy above found out before morning.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Argon usage wall
&lt;/h3&gt;

&lt;p&gt;I covered this above, but it’s the most common way people got burned this week. You pay for AI Ultra because you want Argon. You get through a handful of messages and hit the limit. The r/AntigravityGoogle advice is blunt: don’t upgrade for it. The API charges per token at a published price. The app charges a subscription and then cuts you off at a number nobody printed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The peak-hour batch job
&lt;/h3&gt;

&lt;p&gt;You move a nightly summarization job to DeepSeek V4.1 Flash because it’s 60 cents out. You schedule it at 9pm Central because that’s when your other jobs finish. That’s inside DeepSeek’s peak window, so every token costs double, and you’re paying $1.20 for a model you budgeted at $0.60. In a Hacker News thread about V4.1 Flash, one commenter said they &lt;a href="https://news.ycombinator.com/item?id=50012463" rel="noopener noreferrer"&gt;burned through $50 in a few days&lt;/a&gt; on the cheapest provider on OpenRouter, a quarter of what their Codex subscription costs. Cheap per token isn’t the same as cheap per job. Check what time your jobs actually run.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming
&lt;/h2&gt;

&lt;p&gt;Argon’s API price doubles to $4/$20 on December 1, and that’s the only item in this section with a firm date.&lt;/p&gt;

&lt;p&gt;Mistral Large 4’s open weights are still scheduled for October 31. Kimi K3.1 has a rumored October 29 date, and Grok 4.8 was supposed to land around today, according to the &lt;a href="https://waifuai.github.io/llm-countdowns/" rel="noopener noreferrer"&gt;LLM countdown tracker&lt;/a&gt;. I’ve learned to treat xAI dates as tweets. Claude Fable 5.5 is at about 93 percent on &lt;a href="https://manifold.markets/prismatic/october-2026-ai-model-releases" rel="noopener noreferrer"&gt;Manifold&lt;/a&gt; for October, and Anthropic hasn’t said a word. Haiku 5.5 still doesn’t have an Arena rating, two weeks after launch. MiniMax hasn’t posted M3.1 Flash weights or a model card. DeepSeek V5 is still speculation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;Every headline this week came with a condition attached. Argon is buyable, until December 1 changes the price. DeepSeek is 60 cents, unless the clock says otherwise. Meta’s weights are open, under a license you have to read first. If you only skim the launch posts, you’ll budget off the wrong number.&lt;/p&gt;

&lt;p&gt;So what actually changed for somebody picking a model today? Less than the headlines suggest. The top of the board got a price tag. The bottom of my table held for a third week: MiMo-V2.6-Pro, MiMo-V2.6-Flash, and GLM-5.3-Flash, all under a dollar out, and I’d still start any cost-sensitive project with GLM-5.3-Flash and see whether it falls short before paying 20 times more.&lt;/p&gt;

&lt;p&gt;Next week I’ll see whether DeepSeek’s 1017 snapshot gets an Arena rating, and whether it lands in the band at $1.20. And I’ll keep checking whether Haiku 5.5 ever gets rated.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>openrouter</category>
    </item>
    <item>
      <title>Firecrawl Universal Scrape Can Read Podcasts. The Terms Say You Can't Keep Them.</title>
      <dc:creator>Stephan Miller</dc:creator>
      <pubDate>Thu, 15 Oct 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/eristoddle/firecrawl-universal-scrape-can-read-podcasts-the-terms-say-you-cant-keep-them-3eda</link>
      <guid>https://dev.to/eristoddle/firecrawl-universal-scrape-can-read-podcasts-the-terms-say-you-cant-keep-them-3eda</guid>
      <description>&lt;p&gt;On October 8, &lt;a href="https://firecrawl.link/stephan-miller" rel="noopener noreferrer"&gt;Firecrawl&lt;/a&gt; launched &lt;a href="https://www.firecrawl.dev/blog/universal-scrape" rel="noopener noreferrer"&gt;Universal Scrape&lt;/a&gt;. The scrape endpoint I have been feeding URLs to for this whole series now answers questions about podcasts, people profiles, company financials and website traffic too. Ask it about podcasts and it gets you transcripts.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dev.to/eristoddle/track-new-ai-models-on-the-arena-leaderboard-with-a-70-line-scraper-3f3m"&gt;70-line harness from the Arena post&lt;/a&gt; already does the hard part: run on a schedule, save every result to SQLite, compare this week to last week, speak up when something changes. Point it at podcast mentions instead of a leaderboard and you have a brand monitor. Which podcasts talked about your product this week? Is that number going up? Who mentioned it for the first time?&lt;/p&gt;

&lt;p&gt;Then I read the terms and had to accept them to use the feature. And the terms forbid storing the data, reusing it for a later query, keeping it past the session, and showing it to anyone who isn’t one of your own users. That rules out the harness, the comparison, my AI agents, and other things I haven’t thought of yet.&lt;/p&gt;

&lt;p&gt;So this post is not what I originally planned. It’s about the fine print for every paid provider behind Universal Scrape, plus the version of the podcast tracker that survives it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Universal Scrape Adds&lt;/li&gt;
&lt;li&gt;The Recipe I Was Going to Write&lt;/li&gt;
&lt;li&gt;What Particle’s Terms Actually Say&lt;/li&gt;
&lt;li&gt;I Read the Terms for Every Paid Provider&lt;/li&gt;
&lt;li&gt;
The Tracker That Survives the Terms

&lt;ul&gt;
&lt;li&gt;The second gotcha: don’t pass a domain&lt;/li&gt;
&lt;li&gt;The script&lt;/li&gt;
&lt;li&gt;What I can show you&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read the Schedule Before You Write the Recipe&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Universal Scrape Adds
&lt;/h2&gt;

&lt;p&gt;Two things, really.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Files by URL.&lt;/strong&gt; PDFs, images, Word documents, spreadsheets and presentations, if you can link to them. You pass the URL like any web page and get markdown back. The &lt;a href="https://docs.firecrawl.dev/features/scrape" rel="noopener noreferrer"&gt;scrape docs&lt;/a&gt; put PDF parsing at 1 credit per PDF page. None of that has provider terms attached.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provider data.&lt;/strong&gt; This is &lt;a href="https://dev.to/eristoddle/before-you-write-a-scraper-check-firecrawl-alexandria-2652"&gt;Alexandria&lt;/a&gt;, the data catalog Firecrawl launched a couple of weeks ago, folded into the scrape endpoint. The launch post names the headliners: Apollo, FullEnrich and Data Legion for people and company profiles, Fiscal.ai and Benzinga for financial data, and Particle for podcasts.&lt;/p&gt;

&lt;p&gt;In the CLI, a provider call is a scrape where the URL is a &lt;code&gt;provider/capability&lt;/code&gt; address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firecrawl scrape particle/podcasts/mentions/timeseries &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--options&lt;/span&gt; &lt;span class="s1"&gt;'{"company_id": "anthropic", "interval": "month"}'&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That syntax needs a recent CLI. Mine was 1.23.3, so I updated to 1.26.3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; firecrawl-cli@latest
firecrawl &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="c"&gt;# 1.26.3&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyutf30v02pxh1pf798wb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyutf30v02pxh1pf798wb.jpg" alt="What Universal Scrape Adds" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same plain npm install as the &lt;a href="https://dev.to/eristoddle/firecrawl-cli-setup-skip-the-installer-that-rewrites-your-editors-2klj"&gt;setup post&lt;/a&gt;, so nothing touched my editor configs, and the key still comes from &lt;code&gt;FIRECRAWL_API_KEY&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Recipe I Was Going to Write
&lt;/h2&gt;

&lt;p&gt;Every useful scraping job in this series turned out to be the same job. A scraper tells you what a page says right now. Change needs history, history needs storage, and storage is why the harness exists.&lt;/p&gt;

&lt;p&gt;For podcasts, the plan was one weekly call, a row per episode in SQLite, and three alerts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mentions this week versus the last four&lt;/li&gt;
&lt;li&gt;shows mentioning the term for the first time&lt;/li&gt;
&lt;li&gt;the transcript line where each mention happens, so you can read it without listening to a 90-minute episode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Particle has the tools for all of it. Episode search, transcripts, mention lookups, speaker lists, even which sponsors read ads on which shows. 105 tools, at 5, 15, 25 or 50 credits a call.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Particle’s Terms Actually Say
&lt;/h2&gt;

&lt;p&gt;Before the first call, Particle makes you accept its terms from the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firecrawl alexandria terms show particle &lt;span class="nt"&gt;--json&lt;/span&gt;
firecrawl alexandria terms accept particle &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--terms-version&lt;/span&gt; B-1.0.0 &lt;span class="nt"&gt;--digest&lt;/span&gt; &amp;lt;sha256 from the show output&amp;gt; &lt;span class="nt"&gt;--confirm&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Credit to Firecrawl here. You accept an exact version, pinned by a hash of the document, and the JSON that &lt;code&gt;terms show&lt;/code&gt; returns tells an AI agent to present the terms to a human and wait for an explicit yes. My agent did exactly that. It read them, came back, and told me the recipe was dead before it accepted anything.&lt;/p&gt;

&lt;p&gt;The document is Schedule B, which pulls in &lt;a href="https://particle.pro/legal/tos-data-use-marketplace" rel="noopener noreferrer"&gt;Particle’s Data Use Terms&lt;/a&gt;. The parts that matter, quoted:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(g) Download, save, or store Clips, Full Episode Audio, or Transcripts, other than (i) transient caching necessary for real-time display and the operation of your application, (ii) retaining a response you received, unaltered, so that your users can view that prior response…&lt;/p&gt;

&lt;p&gt;(h) Reuse stored Podcast Data to answer a later or different query. Each query is served by a new request through the Services.&lt;/p&gt;

&lt;p&gt;(i) Where an Automated Agent handles Podcast Data, allow it to retain that data beyond the session context or short-term memory reasonably necessary to process the immediate request. No persistent storage by agents.&lt;/p&gt;

&lt;p&gt;(a) Redistribute, resell, sublicense, or make Podcast Data available to anyone other than your own authorized users…&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Go back through the plan with those in hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The SQLite table is out.&lt;/strong&gt; Saving transcripts is (g). Saving episode rows and comparing them next week is (h), almost word for word: stored data answering a later query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2njlb3ewsdta91cjlfzx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2njlb3ewsdta91cjlfzx.jpg" alt="What Particle's Terms Actually Say" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The agent workflow is out.&lt;/strong&gt; Every post in this series was built with &lt;a href="https://dev.to/eristoddle/what-to-do-when-your-ai-coding-agent-cant-read-a-web-page-2f0i"&gt;a coding agent driving the CLI&lt;/a&gt;. Under (i), the agent can hold the data for the request and that’s it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This blog post is out, mostly.&lt;/strong&gt; You are not one of my authorized users. A table of which shows mentioned which company, in a public post, is (a).&lt;/p&gt;

&lt;p&gt;There is also (j), no training models on it, and section B.7, which says Particle “may not hold licenses from the podcast creators and publishers” for the content. Particle’s position is fair use, and the schedule says that the podcast owners “may not share that assessment.”&lt;/p&gt;

&lt;h2&gt;
  
  
  I Read the Terms for Every Paid Provider
&lt;/h2&gt;

&lt;p&gt;If the podcast provider looks like that, what about the rest? Alexandria has a terms catalog, and &lt;code&gt;terms show&lt;/code&gt; works on any provider ID, so I walked the categories and asked about every provider I could find.&lt;/p&gt;

&lt;p&gt;Most of them have no terms in the catalog at all. Government data, public registries, app stores, package registries, Yahoo Finance. &lt;code&gt;terms show&lt;/code&gt; returns “Provider not found in the accessible terms catalog.” That doesn’t mean no rules. It means Firecrawl has no extra contract for that source, and the source’s own terms of service apply the way they would to any scrape.&lt;/p&gt;

&lt;p&gt;The commercial partners each carry a lettered schedule. Seven of them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;th&gt;Store it?&lt;/th&gt;
&lt;th&gt;Publish it?&lt;/th&gt;
&lt;th&gt;Accept first?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Similarweb (G)&lt;/td&gt;
&lt;td&gt;Website traffic&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No.&lt;/strong&gt; Not even cached. Each data point answers only the query that fetched it, in that session&lt;/td&gt;
&lt;td&gt;To your users, one query at a time, with “Insights by Similarweb”, their logo and a link&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Particle (B)&lt;/td&gt;
&lt;td&gt;Podcasts&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No&lt;/strong&gt; , beyond an unaltered past response&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apollo (F)&lt;/td&gt;
&lt;td&gt;Contacts, companies&lt;/td&gt;
&lt;td&gt;Yes, for your own sales, marketing and recruiting&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No&lt;/strong&gt; , not even through an agent’s output&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FullEnrich (A)&lt;/td&gt;
&lt;td&gt;Contacts&lt;/td&gt;
&lt;td&gt;For your own sales, marketing and recruiting&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Legion (H)&lt;/td&gt;
&lt;td&gt;People, companies&lt;/td&gt;
&lt;td&gt;Only in your CRM and internal systems&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No&lt;/strong&gt; (your own analyses are yours)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benzinga (C)&lt;/td&gt;
&lt;td&gt;Market news&lt;/td&gt;
&lt;td&gt;As needed to serve your own product&lt;/td&gt;
&lt;td&gt;Inside your product, to your users&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fiscal.ai (D)&lt;/td&gt;
&lt;td&gt;Financials, filings&lt;/td&gt;
&lt;td&gt;Yes, within your apps&lt;/td&gt;
&lt;td&gt;Inside your apps, to your users&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;“Accept first?” is the &lt;code&gt;required&lt;/code&gt; flag. When it says No, the call goes through without an acceptance step. The schedules still describe how you are allowed to use the data, and nothing in them suggests skipping the acceptance step lets you skip the rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2l2drgkxqish07t90ik2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2l2drgkxqish07t90ik2.jpg" alt="I Read the Terms for Every Paid Provider" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So it sorts into three piles. The contact providers are built for your sales team and forbid publishing. Similarweb and Particle forbid keeping anything. The financial providers leave you room to build a product.&lt;/p&gt;

&lt;p&gt;None of this is Firecrawl being sneaky. Licensed data has always come with rules like these. What changed is that it now sits behind the same &lt;code&gt;firecrawl scrape&lt;/code&gt; you use on a public web page, where the only rules are robots.txt and the site’s terms. One command, two completely different legal situations, and nothing in the syntax tells you which one you are in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tracker That Survives the Terms
&lt;/h2&gt;

&lt;p&gt;The thing (h) forbids, keeping your own history to answer later questions, is a thing Particle sells you instead. &lt;code&gt;podcasts/mentions/timeseries&lt;/code&gt; costs 15 credits and returns the whole history, bucketed by day, week or month, in one call. You don’t need a database if every run asks for everything.&lt;/p&gt;

&lt;p&gt;I pointed it at Anthropic, monthly, since January. The episode counts climbed steeply all year. It looked like a story. Then I ran the same call on Coca-Cola as a control (a company that didn’t get more famous in 2026), and it climbed steeply too.&lt;/p&gt;

&lt;p&gt;That is not Anthropic or Coca-Cola. That is Particle’s index growing. More shows transcribed, more episodes covered, more mentions of everybody. A raw mention count from a source whose coverage changes every month will tell you your brand is exploding when the source is the thing exploding.&lt;/p&gt;

&lt;p&gt;The fix is old: divide by a control. Same source, same window, a company whose real share of the conversation should hold steady. Whatever index growth inflates in one, it inflates in the other.&lt;/p&gt;

&lt;h3&gt;
  
  
  The second gotcha: don’t pass a domain
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;company_id&lt;/code&gt; says it takes a slug, a domain or an ID. &lt;code&gt;anthropic.com&lt;/code&gt; worked. &lt;code&gt;coca-cola.com&lt;/code&gt; came back as &lt;strong&gt;Simply Orange&lt;/strong&gt; , one juice brand out of Coca-Cola’s two hundred, with a handful of mentions. No error, no warning. If I hadn’t looked at the &lt;code&gt;company&lt;/code&gt; block in the response, I’d have used a juice brand as my control and believed the result.&lt;/p&gt;

&lt;p&gt;So the script resolves names first with &lt;code&gt;entities/search&lt;/code&gt; (5 credits) and takes the exact match.&lt;/p&gt;

&lt;h3&gt;
  
  
  The script
&lt;/h3&gt;

&lt;p&gt;No SQLite, no saved files. It prints to the terminal and forgets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo8yqf7fv53js7kfvs76i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo8yqf7fv53js7kfvs76i.jpg" alt="The script" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;firecrawl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scrape&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;particle/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--options&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):])[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alexandria&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;company_slug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Never pass a bare domain: coca-cola.com resolved to Simply Orange.
&lt;/span&gt;    &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;entities/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;})[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;exact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;match_quality&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;exact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no company found for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;!r}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;company&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exact&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;!r}&lt;/span&gt;&lt;span class="s"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;slug&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;podcasts/mentions/timeseries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interval&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;month&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;published_after&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;episode_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;buckets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;since&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-01-01&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;company_slug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;company_slug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;month &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; episodes per &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; episode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;6.2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; __main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;podcast_share&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Anthropic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The Coca-Cola Company&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each run is two searches and two timeseries calls: 40 credits. Monthly, that’s 4% of the free 1,000. Weekly, about 17%. Daily is 1,200, which is more than the free plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I can show you
&lt;/h3&gt;

&lt;p&gt;And (a) bites the post itself: Particle’s counts are Podcast Data, so I’m not printing them. The ratio is a number I computed from them, which I think puts it on my side of the line. I am not a lawyer, and you should make that call for your own use, not borrow mine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;month Anthropic episodes per The Coca-Cola Company episode
2026-01 1.57
2026-02 2.94
2026-03 3.87
2026-04 3.27
2026-05 3.15
2026-06 3.57
2026-07 2.78
2026-08 3.14
2026-09 4.89
2026-10 3.89

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that against the raw curve, which climbed all year. Corrected for index growth, Anthropic’s share roughly doubled from January to February and then sat around three for six months. September is the only real spike. October is a partial month as I write this. The steep line was mostly Particle getting bigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read the Schedule Before You Write the Recipe
&lt;/h2&gt;

&lt;p&gt;The rule from the &lt;a href="https://dev.to/eristoddle/before-you-write-a-scraper-check-firecrawl-alexandria-2652"&gt;Alexandria post&lt;/a&gt; was check the catalog before you write a scraper. Universal Scrape adds a step after that: check the terms before you write anything that stores, compares or publishes.&lt;/p&gt;

&lt;p&gt;The check is one free command per provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firecrawl alexandria terms show &amp;lt;provider&amp;gt; &lt;span class="nt"&gt;--json&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it says the provider is not in the terms catalog, you’re in normal scraping territory, with the site’s own terms and everything the series has said so far. If it returns a schedule, search it for “store”, “retain”, “available to” and “agent” before you design anything. Those four words decide whether your idea is a cron job, a dashboard for your own team, or nothing.&lt;/p&gt;

&lt;p&gt;My podcast tracker ended up as a 40-line script that forgets everything it learns the moment it prints. That’s less than I wanted. It’s also the only version I can actually run, and it gets right what the version I planned would have gotten wrong: the growth curve was mostly the index.&lt;/p&gt;

&lt;p&gt;The financial providers are the ones whose terms let you build something real, which makes Fiscal.ai the next thing I want to look at.&lt;/p&gt;

</description>
      <category>firecrawl</category>
      <category>universalscrape</category>
    </item>
  </channel>
</rss>
