<?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: Jonathan Murray</title>
    <description>The latest articles on DEV Community by Jonathan Murray (@jon_at_backboardio).</description>
    <link>https://dev.to/jon_at_backboardio</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%2F3824580%2Fcbf3ef23-2d0b-4576-90ff-0d46b2119ea8.png</url>
      <title>DEV Community: Jonathan Murray</title>
      <link>https://dev.to/jon_at_backboardio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jon_at_backboardio"/>
    <language>en</language>
    <item>
      <title>Jev by TypeSafe on Backboard.io</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Thu, 17 Sep 2026 22:54:50 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/jev-by-typesafe-on-backboardio-43a5</link>
      <guid>https://dev.to/jon_at_backboardio/jev-by-typesafe-on-backboardio-43a5</guid>
      <description>&lt;p&gt;No fancy long posts here, just cold hard facts. The viral model Jev, is now on backboard:&lt;/p&gt;

&lt;p&gt;HUGE ANNOUNCEMENT: Backboard.io now supports TypeSafe Jev — System One Models&lt;/p&gt;

&lt;p&gt;• Added Jev support for structured decisions: Choice, Score, and Noul (true/false probability).&lt;br&gt;
• Use the existing message API with llm_provider="typesafe" and system_one.questions.&lt;br&gt;
• Evaluate text or structured data, with conversation history included.&lt;br&gt;
• Receive typed answers, probabilities, confidence where supported, and token usage.&lt;br&gt;
• Added Python and TypeScript SDK support; Python SDK v1.5.19 is available on PyPI.&lt;br&gt;
• Published Core Concepts and SDK guides with examples and complete response documentation.&lt;br&gt;
Supported models: jev-latest.&lt;/p&gt;

&lt;p&gt;docs&lt;br&gt;
• &lt;a href="https://docs.backboard.io/sdk/system-one" rel="noopener noreferrer"&gt;https://docs.backboard.io/sdk/system-one&lt;/a&gt;&lt;br&gt;
• &lt;a href="https://docs.backboard.io/concepts/system-one" rel="noopener noreferrer"&gt;https://docs.backboard.io/concepts/system-one&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Make a Runway Clone in one shot, or something else!</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Thu, 17 Sep 2026 17:20:20 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/make-a-runway-clone-in-one-shot-or-something-else-5hdg</link>
      <guid>https://dev.to/jon_at_backboardio/make-a-runway-clone-in-one-shot-or-something-else-5hdg</guid>
      <description>&lt;p&gt;&lt;em&gt;i'm jon, i co-founded &lt;a href="https://backboard.io" rel="noopener noreferrer"&gt;backboard.io&lt;/a&gt;. this is a launch post. it's short and there's code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;video models are live on backboard.&lt;/p&gt;

&lt;p&gt;Here is a video of me and my dog rapping if you don't believe me.&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/wQt1TmV-nx4" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;ByteDance's Seedance family is in, served through OpenRouter, along with the rest of the OpenRouter video catalog.&lt;/p&gt;

&lt;p&gt;that's the news. here's why you should care.&lt;/p&gt;

&lt;h2&gt;
  
  
  video is the worst part of the stack to glue
&lt;/h2&gt;

&lt;p&gt;text you've figured out. images, mostly. video is where it gets ugly.&lt;/p&gt;

&lt;p&gt;every provider has its own job api. submit. get an id. poll. poll again. time out. retry. download the file. store it somewhere. pass a url back to your agent. hope the agent remembers what it made two turns ago.&lt;/p&gt;

&lt;p&gt;that's a whole service. for one feature. and it's different for every model.&lt;/p&gt;

&lt;p&gt;so we built it once. same way we did memory, rag, routing, voice and image.&lt;/p&gt;

&lt;h2&gt;
  
  
  what's live
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ByteDance Seedance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bytedance/seedance-2.5&lt;/code&gt; (up to 30s, with audio)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bytedance/seedance-2.0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bytedance/seedance-2.0-fast&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;bytedance/seedance-2.0-mini&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;the rest of the OpenRouter video catalog&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Veo 3.1, Wan 3.0, Kling 3.0, Hailuo 3, Grok Imagine and more&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;client.list_video_models()&lt;/code&gt; shows exactly what's live and what each model supports. &lt;code&gt;client.get_video_model(model_id)&lt;/code&gt; gives you one model's limits.&lt;br&gt;
six ways in:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;text to video&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;first frame to video (animate an image)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;first and last frame&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;video to video (edit, extend, upscale)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;references (images, audio or video as a guide)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mixed references&lt;/p&gt;
&lt;h2&gt;
  
  
  the code
&lt;/h2&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it's the &lt;code&gt;add_message&lt;/code&gt; call you already make. four extra keys.&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;backboard&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BackboardClient&lt;/span&gt;

&lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&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;llm_provider&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;openai&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;model_name&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;gpt-4.1&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;video_generation&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;auto&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;video_model_provider&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;openrouter&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;video_model_name&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;bytedance/seedance-2.0-fast&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;video_config&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;duration&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;aspect_ratio&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;16:9&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;resolution&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;720p&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="k"&gt;async&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BackboardClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BACKBOARD_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1900&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;assistant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_assistant&lt;/span&gt;&lt;span class="p"&gt;(&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;video assistant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assistant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assistant_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;thread_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a paper boat drifting down a rainy city gutter, golden hour&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&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;message&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&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;media&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;message&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;generated_media&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="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="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;document_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;media&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;asyncio&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="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;no job queue. no polling loop. we poll for you, for up to 30 minutes, and hand back the clip.&lt;/p&gt;

&lt;p&gt;every clip comes back in &lt;code&gt;generated_media&lt;/code&gt; with a &lt;code&gt;document_id&lt;/code&gt; and a url. it lives in the thread. next to the memory. next to everything else your agent already knows.&lt;/p&gt;

&lt;p&gt;want to animate an image instead? add a file.&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="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slow push in, steam rising off the coffee&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&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;start.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;two files is first frame plus last frame. an &lt;code&gt;.mp4&lt;/code&gt; is video to video.&lt;/p&gt;

&lt;h2&gt;
  
  
  the part that matters: it's a thread
&lt;/h2&gt;

&lt;p&gt;the clip isn't a loose file. it's in the conversation. so the next turn can just be:&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="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;same shot, but at night. neon reflections in the water.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;no re-uploading. no passing urls around. the agent knows what it made, because it made it in the same thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  stuff worth knowing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;the model decides. &lt;code&gt;video_generation="auto"&lt;/code&gt; hands your assistant a &lt;code&gt;generate_video&lt;/code&gt; tool. it calls it when the ask needs a video. it won't render one because you said hi.&lt;/li&gt;
&lt;li&gt;the chat model and the video model are picked separately. reason with one, render with another.&lt;/li&gt;
&lt;li&gt;pass the video settings on every turn, follow-ups included. that's the one gotcha.&lt;/li&gt;
&lt;li&gt;video takes minutes. use &lt;code&gt;stream=True&lt;/code&gt; and a long client timeout. we use 1900 seconds.&lt;/li&gt;
&lt;li&gt;a client timeout doesn't cancel the job upstream. don't auto-retry, or you'll render it twice.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;video_config&lt;/code&gt; covers duration, resolution, aspect ratio, size, audio, seed, upscale and provider routing. only where the model supports it. check &lt;code&gt;get_video_model()&lt;/code&gt; first.&lt;/li&gt;
&lt;li&gt;frames have to be images. a last frame needs a first frame. don't mix frames with a source video or references.&lt;/li&gt;
&lt;li&gt;you're billed the actual cost the provider returns. not an estimate. job ids and costs sit in thread metadata if you need to audit.&lt;/li&gt;
&lt;li&gt;don't need a thread? there's a stateless path too, &lt;code&gt;operation="generate_video"&lt;/code&gt;. &lt;a href="https://docs.backboard.io/sdk/stateless-videos" rel="noopener noreferrer"&gt;docs here&lt;/a&gt;
## the actual point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;swap &lt;code&gt;bytedance/seedance-2.0-fast&lt;/code&gt; for &lt;code&gt;google/veo-3.1-fast&lt;/code&gt;. one string. nothing else moves.&lt;/p&gt;

&lt;p&gt;that's the whole backboard thing. the model is a parameter. text, voice, image and now video, behind one key, with memory under all of it. so your agent doesn't forget what it just made.&lt;/p&gt;

&lt;p&gt;you were going to write that polling loop this weekend. don't.&lt;/p&gt;

&lt;p&gt;get a key: &lt;a href="https://app.backboard.io" rel="noopener noreferrer"&gt;app.backboard.io&lt;/a&gt;&lt;br&gt;
video docs: &lt;a href="https://docs.backboard.io/sdk/video-tool" rel="noopener noreferrer"&gt;docs.backboard.io/sdk/video-tool&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>showdev</category>
      <category>startup</category>
    </item>
    <item>
      <title>OpenAI can't rule out that it stole its most recent breakthrough</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Tue, 08 Sep 2026 20:51:56 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/openai-cant-rule-out-that-it-stole-its-most-recent-breakthrough-12d2</link>
      <guid>https://dev.to/jon_at_backboardio/openai-cant-rule-out-that-it-stole-its-most-recent-breakthrough-12d2</guid>
      <description>&lt;p&gt;A mathematician spent a year on one of the hardest open problems in math. He asked OpenAI a simple question. Did you train on my sessions? Today they answered. Sort of.&lt;/p&gt;

&lt;p&gt;Here is what happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Tristan Buckmaster is a math professor at NYU. He and Levent Alpöge spent most of the past year attacking finite-time blowup for fluid equations, the family of problems that includes the Navier-Stokes Millennium Prize. They worked with LLMs the whole way. Claude, Codex, GPT-5.6 Sol, Astra. By August 15 they had blowup results for Boussinesq and 3D Euler. By August 22 they had a proof verified in Lean.&lt;/p&gt;

&lt;p&gt;Every draft of the project went through Codex. His words, from his &lt;a href="https://cims.nyu.edu/~tristanb/statement.pdf" rel="noopener noreferrer"&gt;statement&lt;/a&gt;: "our sessions in Codex, into which we had been putting all our drafts for the whole of this project."&lt;/p&gt;

&lt;h2&gt;
  
  
  The call
&lt;/h2&gt;

&lt;p&gt;September 3. Rumors start moving. Buckmaster emails his contact at OpenAI to ask what's going on. Within days he's on a call with Sébastien Bubeck. He's told an internal OpenAI model has produced a proof of finite-time blowup for forced Navier-Stokes. About 100 pages. Same smooth-forcing setup he and Alpöge had quietly chosen.&lt;/p&gt;

&lt;p&gt;He asks when the first prompt was sent. It takes a while to get an answer. Eventually it's agreed: in the past few days, after information about their work had reached OpenAI.&lt;/p&gt;

&lt;p&gt;Then he asks the real question. Was the model trained on, or did it have access to, their Codex sessions?&lt;/p&gt;

&lt;p&gt;He's told the model did not look up user data.&lt;/p&gt;

&lt;p&gt;He asks again. About training specifically.&lt;/p&gt;

&lt;p&gt;No answer.&lt;/p&gt;

&lt;p&gt;That was the state of things when he went public last night. Alongside it: two proposals to coordinate release, a request to drop Alpöge from authorship because Alpöge works at Anthropic, and a line he quotes directly: "If you don't want me to be nice, then I don't have to be nice." OpenAI's first response called the allegations "false and inflammatory." Bubeck has since called the career remark "ill-chosen" and retracted 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%2Fgjxaflttzulxpva2gpqu.jpeg" 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%2Fgjxaflttzulxpva2gpqu.jpeg" alt=" " width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The answer
&lt;/h2&gt;

&lt;p&gt;Today OpenAI &lt;a href="https://x.com/OpenAI" rel="noopener noreferrer"&gt;posted a statement&lt;/a&gt;. Read this part slowly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"While unlikely, we cannot rule out that de-identified data derived from their usage of our products helped improve our models."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the training question. Answered.&lt;/p&gt;

&lt;p&gt;Not "we did not train on it." Not "their sessions were excluded." They cannot rule it out. A year of unpublished work on a Millennium Prize problem, and the company whose model produced the result cannot rule out that the work was in the training set.&lt;/p&gt;

&lt;p&gt;Notice how carefully the statement is built. It says no specific user data was "accessed." That's a retrieval claim. It says the researchers and agents did not "see" the work. That's a visibility claim. Training is a third thing, and on training the answer is a shrug.&lt;/p&gt;

&lt;p&gt;They also say the proofs differ significantly and the Euler results are different, forced versus unforced. Maybe so. Nobody outside OpenAI has seen their proof yet, including Buckmaster. That part will get sorted out by mathematicians.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters to you
&lt;/h2&gt;

&lt;p&gt;You don't have a Millennium Prize problem in your Codex history. You have your codebase. Your architecture decisions. The thing you've been building for eight months that isn't public yet.&lt;/p&gt;

&lt;p&gt;Consumer Codex sessions are training data by default. That is not a leak. That is the product. Buckmaster's drafts were "de-identified data derived from usage." So are yours.&lt;/p&gt;

&lt;p&gt;The lesson isn't that OpenAI did something exotic here. It's that the default did exactly what the default does, and for once it happened to someone whose work was important enough that the question got asked out loud, and answered in writing.&lt;/p&gt;

&lt;p&gt;"We cannot rule it out" is the honest answer. It's also the only answer they can give. Think about what that means for everything you've ever pasted in.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources: Buckmaster's &lt;a href="https://cims.nyu.edu/~tristanb/statement.pdf" rel="noopener noreferrer"&gt;statement&lt;/a&gt;, the &lt;a href="https://x.com/OpenAI" rel="noopener noreferrer"&gt;OpenAI statement&lt;/a&gt;, &lt;a href="https://techcrunch.com/2026/09/08/openai-fought-dirty-on-career-making-math-problem-says-nyu-mathematician/" rel="noopener noreferrer"&gt;TechCrunch&lt;/a&gt;, &lt;a href="https://fortune.com/2026/09/08/openai-says-it-cracked-navier-stokes-math-grand-challenge-buckmaster-accusation-cheating-intimidation-tao-lament/" rel="noopener noreferrer"&gt;Fortune&lt;/a&gt;, &lt;a href="https://the-decoder.com/openai-researcher-allegedly-pressured-mathematician-to-drop-anthropic-co-author-from-math-breakthrough-paper/" rel="noopener noreferrer"&gt;The Decoder&lt;/a&gt;, &lt;a href="https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan" rel="noopener noreferrer"&gt;OpenAI data policy&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>news</category>
      <category>discuss</category>
      <category>mathematics</category>
    </item>
    <item>
      <title>There Are Only Two Ways to Make Money in Software.</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Sat, 05 Sep 2026 17:09:06 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/there-are-only-two-ways-to-make-money-in-software-18n6</link>
      <guid>https://dev.to/jon_at_backboardio/there-are-only-two-ways-to-make-money-in-software-18n6</guid>
      <description>&lt;p&gt;my team builds AI infrastructure, so yes, i have a horse in this race. the horse shows up at the end, clearly labeled. the history comes first, and the history is free.&lt;/p&gt;

&lt;p&gt;jim barksdale, back when he ran netscape, said the only two ways to make money in software are bundling and unbundling.&lt;/p&gt;

&lt;p&gt;people quote it like a joke. it's not a joke. it's the whole industry in one sentence, and it explains exactly what happened to your sprint board.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=-YtI6g3d71Y" rel="noopener noreferrer"&gt;Jim Barksdale TED Talk - The Power of Networks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the cycle, in 90 seconds&lt;/p&gt;

&lt;p&gt;microsoft bundled office. google unbundled it into free web apps. then it bundled them back into workspace.&lt;/p&gt;

&lt;p&gt;cable bundled channels. netflix unbundled them. now netflix has ads, tiers, and live sports. that's a cable bundle with a different logo.&lt;/p&gt;

&lt;p&gt;craigslist was one bundle. airbnb, zillow, indeed, tinder each took one row. then each of them started bundling again: payments, insurance, messaging, verification.&lt;/p&gt;

&lt;p&gt;aws unbundled the data center into 200 services. snowflake and databricks bundled the useful ones back together and got carried by the very clouds they sit on top of.&lt;/p&gt;

&lt;p&gt;same shape every time. someone unbundles to win on choice and price. the seams between the pieces start costing more than the pieces. someone bundles so nobody has to touch the seams again. repeat.&lt;/p&gt;

&lt;p&gt;the part people miss: in every one of those cycles, there's a stretch in the middle where the user is the one holding the seams. that stretch is miserable and it always ends the same way. somebody does the bundling for you.&lt;/p&gt;

&lt;p&gt;AI skipped a step&lt;/p&gt;

&lt;p&gt;here's what's weird about AI. it unbundled before it ever bundled.&lt;/p&gt;

&lt;p&gt;there was never an office moment. no single integrated product everyone used and then got picked apart. the stack arrived pre-shattered.&lt;/p&gt;

&lt;p&gt;a model provider. a second model provider for when the first one is down or expensive. a vector database. an embeddings provider. a memory service. a rag framework. an orchestration layer. observability. a gateway to route between all of it.&lt;/p&gt;

&lt;p&gt;that's eight or nine vendors for one app. i've counted this before and it still bothers me. nobody designed it. it accreted, one sprint and one free tier at a time.&lt;/p&gt;

&lt;p&gt;every one of those vendors is a great unbundler. best vector database. best memory. best router. each one wins its row.&lt;/p&gt;

&lt;p&gt;nobody owns the seams. you do. and the seams are where all the work is.&lt;/p&gt;

&lt;p&gt;the seams are where your time goes&lt;/p&gt;

&lt;p&gt;be honest about what you spent last quarter on.&lt;/p&gt;

&lt;p&gt;not on the agent. on the glue. the retry logic between the gateway and the model. the schema translation between the rag framework and the vector db. the memory that's written in one place and read from another and never quite agrees with itself. state living in three systems with three retention policies.&lt;/p&gt;

&lt;p&gt;then a better model ships and you do it all again, because the glue was written for the old one.&lt;/p&gt;

&lt;p&gt;this is the unbundled tax. it's the same tax people paid stitching an email client, a calendar, a doc editor, and a file store together before workspace existed. everyone paid it, everyone hated it, and it felt normal because everyone was paying it.&lt;/p&gt;

&lt;p&gt;and here's the thing about the tax. it's not your job. nobody hired you to integrate vendors. they hired you to ship the agent. the glue is the work you do instead of the work you were hired for.&lt;/p&gt;

&lt;p&gt;you are in the miserable middle&lt;/p&gt;

&lt;p&gt;look at any of the cycles above. the middle stretch, where users hold the seams, lasts exactly as long as it takes for someone to bundle it back. then it's over and nobody misses it. nobody is nostalgic for configuring imap.&lt;/p&gt;

&lt;p&gt;AI is in that stretch right now. the difference is that this time the stretch has been unusually long, because the parts kept changing under everyone's feet and nobody could sit still long enough to assemble them.&lt;/p&gt;

&lt;p&gt;we sat still. that's the horse.&lt;/p&gt;

&lt;p&gt;the horse, as promised&lt;/p&gt;

&lt;p&gt;we built backboard so you don't have to bundle anything. the bundling is done.&lt;/p&gt;

&lt;p&gt;one api, one key: memory (first on the LoCoMo and LongMemEval benchmarks, receipts on github), routing across 17,000+ models, agentic hybrid rag, and stateful threads. not four services with one invoice. one system where memory, retrieval, routing, and state already share state, so there's nothing to translate between them and no glue to write.&lt;/p&gt;

&lt;p&gt;the model is a parameter you pass. when a better one ships, you change a string. you don't re-platform.&lt;/p&gt;

&lt;p&gt;it runs where you already build. native in backboard studio and in R-CLI, our open-source coding harness (MIT, highest publicly reported score on terminal bench 2.1 at 84.3%, above every published result). same key and same memory from cursor, claude code, or vs code if that's your setup. no migration.&lt;/p&gt;

&lt;p&gt;pip install backboard-sdk, one key, and the eight-vendor diagram becomes one box. free tier is $5 in memory credits, no card.&lt;/p&gt;

&lt;p&gt;and now the half of the bundle nobody talks about.&lt;/p&gt;

&lt;p&gt;backboard is available on AWS marketplace. that sentence is boring until you know what it does for you. it means your company buys the bundled stack through the cloud bill it already pays, with committed AWS spend it already negotiated, deployed inside its own AWS account. no new vendor onboarding. no ninth security review. no six-week procurement thread where you defend a vector database to someone in finance. the same reason snowflake and databricks get carried by the clouds applies here: a bundled stack is easier to buy through the cloud than through a procurement process, and it's easier to get approved because there's one thing to approve.&lt;/p&gt;

&lt;p&gt;so both seams are gone. the technical one, where you wrote glue. and the purchasing one, where you wrote justifications. we did both so you can go back to shipping the agent.&lt;/p&gt;

&lt;p&gt;the objection&lt;/p&gt;

&lt;p&gt;"a bundle is lock-in with better marketing."&lt;/p&gt;

&lt;p&gt;fair. it was true for cable and it's true for most suites. two answers.&lt;/p&gt;

&lt;p&gt;first, the exit is real. memory is exportable through crud endpoints. routing is model-agnostic. byok means we never hold your provider keys. you can leave, which is the only honest answer to lock-in, and it's why people stay.&lt;/p&gt;

&lt;p&gt;second, the compute is never ours. you pay your cloud directly. we don't resell it at a markup, which is where most bundles quietly make their margin and where most bundle resentment comes from.&lt;/p&gt;

&lt;p&gt;the whole post in four lines&lt;/p&gt;

&lt;p&gt;software alternates between bundling and unbundling, and in the middle the user holds the seams.&lt;/p&gt;

&lt;p&gt;AI unbundled before it ever bundled. you're holding the seams. that's why your sprint board is glue.&lt;/p&gt;

&lt;p&gt;the re-bundle is done. memory, retrieval, routing, and state behind one key, the model as a parameter.&lt;/p&gt;

&lt;p&gt;and it's on the cloud bill you already pay, so the last seam, getting it approved, is gone too.&lt;/p&gt;

&lt;p&gt;go get a key at backboard.io and delete some glue this week. &lt;/p&gt;

&lt;p&gt;Comment if you want a promo code for some dev credits.&lt;/p&gt;

</description>
      <category>product</category>
      <category>saas</category>
      <category>software</category>
    </item>
    <item>
      <title>I Watched Our Interns Play Valorant for Three Hours. Put Your Rank on the Resume.</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Sat, 05 Sep 2026 13:49:09 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/i-watched-our-interns-play-valorant-for-three-hours-put-your-rank-on-the-resume-8jd</link>
      <guid>https://dev.to/jon_at_backboardio/i-watched-our-interns-play-valorant-for-three-hours-put-your-rank-on-the-resume-8jd</guid>
      <description>&lt;p&gt;Last week of summer with our interns we skipped the goodbye lunch and booked an esports arena. Split them into teams. Valorant. Best of whatever until the room kicked us out.&lt;/p&gt;

&lt;p&gt;I run go to market at a startup. I have sat through a lot of team exercises. Trust falls. Escape rooms. A guy with a flip chart. None of them came close to what I watched for three hours in that room.&lt;/p&gt;

&lt;p&gt;The quiet ones were calling rotations. The loud ones shut up and listened. Someone who had never touched the game was getting coached mid round by someone who was clearly very good and clearly not making a thing of it. Lose a round, thirty seconds of "ok what happened," next round. Nobody sulked. Nobody quit. The room got louder every map.&lt;/p&gt;

&lt;p&gt;Then I went home and thought about which of those people ship the thing at 2am and fix the demo at 8am. Same people. And almost none of them had ever mentioned they played. Not in the interview. Not on the resume. Not once.&lt;/p&gt;

&lt;p&gt;So this one is for you. The one who peaked Diamond, or Immortal, or Radiant, and wrote "strong communicator" on the resume instead.&lt;/p&gt;

&lt;p&gt;You are underselling the most relevant thing you have ever done.&lt;/p&gt;

&lt;h2&gt;
  
  
  the ladder does not care about your story
&lt;/h2&gt;

&lt;p&gt;A resume is a story you tell about yourself. Your rank is a number the world assigned to you.&lt;/p&gt;

&lt;p&gt;You could not network your way there. You could not talk your way through a placement match. Every game was a fresh evaluation against people trying to end you, and the rating moved whether you liked the result or not.&lt;/p&gt;

&lt;p&gt;That is what working at a startup is. The market does not read the pitch. It uses the product or it does not. You already know how to live inside a number you cannot argue with. Most people your age have never had to.&lt;/p&gt;

&lt;h2&gt;
  
  
  you lose four out of ten and queue again
&lt;/h2&gt;

&lt;p&gt;A 60% win rate at high rank is elite. Read that again. You lost four games out of ten, closed the scoreboard, and queued.&lt;/p&gt;

&lt;p&gt;Do you know how rare that is? Most people lose twice, tilt, blame the team, and go do something else with their evening. You built a loop instead. Lose. Watch it back. Fix one thing. Next one at full intensity. No sulking. No speech.&lt;/p&gt;

&lt;p&gt;That is a startup week. Demo breaks. Deal slips. Benchmark run dies at 3am. Queue again. You have done this loop ten thousand times. You just did it with a crosshair.&lt;/p&gt;

&lt;h2&gt;
  
  
  your comms are already better than the senior dev's
&lt;/h2&gt;

&lt;p&gt;"Two A short. One low. Rotating." Nobody gives a TED talk in a clutch round. Nobody goes quiet either.&lt;/p&gt;

&lt;p&gt;Now think about the worst standup you have ever sat in. Someone spends eleven minutes explaining why the thing broke. Someone else says nothing and then it turns out they were blocked all week.&lt;/p&gt;

&lt;p&gt;An eighteen person company is a five stack in a clutch round every day. Short, precise, useful updates are the whole job. You have years of reps on this. You got them for free. You just never thought of it as a skill.&lt;/p&gt;

&lt;h2&gt;
  
  
  you fill
&lt;/h2&gt;

&lt;p&gt;What do you main? Now what do you play when the comp needs something else?&lt;/p&gt;

&lt;p&gt;If you are any good, you fill. You controller when the duelist instalocks. You IGL when the IGL is missing. You hate it a little and you do it anyway, because the point is winning, not your slot.&lt;/p&gt;

&lt;p&gt;At a startup "not my job" is a firing offence. The person who goes backend to demo prep to support tickets in one afternoon is the person the company gets built around. You have been that person since Silver. Fillers build companies. Instalockers build politics.&lt;/p&gt;

&lt;h2&gt;
  
  
  you already watch your own tape
&lt;/h2&gt;

&lt;p&gt;You watch your losses. Not the highlights. The losses. Where was my crosshair. Why did I peek that. What did I know in that moment and what did I ignore.&lt;/p&gt;

&lt;p&gt;Postmortems are a religion in esports and a suggestion in most companies. An engineer who reviews their own failures without a manager standing over them gets better with zero supervision. There is no supervision at a startup. That is the entire game. You have been playing it for years.&lt;/p&gt;

&lt;h2&gt;
  
  
  the grind is the resume
&lt;/h2&gt;

&lt;p&gt;Silver to Immortal is not talent. It is a thousand hours of deliberate discomfort. Two hundred dry runs of the same lineup. Deathmatch at midnight because your flick was off.&lt;/p&gt;

&lt;p&gt;That is the exact texture of building something from nothing. Boring, repetitive, unglamorous, at full intensity, because you believe the number goes up eventually.&lt;/p&gt;

&lt;p&gt;You have done it once. So you know you can do it again. The person next to you in the interview with the nicer school and the cleaner resume does not know that about themselves yet. That is the gap. That is your edge. And you left it off the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  what to actually do
&lt;/h2&gt;

&lt;p&gt;Put it on. Peak rank, game, how long it took. One line.&lt;/p&gt;

&lt;p&gt;When they ask about it, and they will, do not get sheepish. Tell them what it cost. Tell them where you plateaued and why. Tell them what role you ended up playing versus the one you wanted. That answer is worth more than any project on your GitHub, and it is the one answer nobody else in the pile can fake.&lt;/p&gt;

&lt;p&gt;Some hiring managers will screen you out for it. Good. You did not want to work there. The ones who light up are the ones who will actually let you play.&lt;/p&gt;

&lt;h2&gt;
  
  
  so we are running a league
&lt;/h2&gt;

&lt;p&gt;Backboard Valorant League. University teams, the whole school year, two games a week on Twitch, finals in Toronto in the spring.&lt;/p&gt;

&lt;p&gt;Partly because three hours in that arena did more for our team than any offsite I have run. Mostly because the people who show up for something like this are exactly the people every startup should be fighting over, and I would like to meet you before someone else does.&lt;/p&gt;

&lt;p&gt;If you are on a university team, comment below. Rank is not a requirement. Showing up is.&lt;/p&gt;

&lt;p&gt;I co-founded &lt;a href="https://backboard.io" rel="noopener noreferrer"&gt;Backboard&lt;/a&gt;. A lot of the team plays. It shows. We're going to start a Valorant league.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Matrix Wasn't A Battery Farm. It Was A GPU Cluster Made Of Human Brains.</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Fri, 28 Aug 2026 15:25:20 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/the-matrix-wasnt-a-battery-farm-it-was-a-gpu-cluster-made-of-human-brains-23e5</link>
      <guid>https://dev.to/jon_at_backboardio/the-matrix-wasnt-a-battery-farm-it-was-a-gpu-cluster-made-of-human-brains-23e5</guid>
      <description>&lt;p&gt;Nvidia is worth more than most countries because we cannot figure out how to do cheap inference.&lt;/p&gt;

&lt;p&gt;There are eight billion units walking around that do it on 20 watts.&lt;/p&gt;

&lt;p&gt;I rewatched The Matrix recently and got stuck on the same thing everyone gets stuck on. Batteries.&lt;/p&gt;

&lt;p&gt;Morpheus holds up a Duracell and tells Neo the machines are farming humans for electricity. Bio-electricity, body heat, 25,000 BTUs, the whole speech. It's a great scene. It's also thermodynamic nonsense. You are feeding these people liquefied protein slurry. If you want energy out of the slurry, burn the slurry. Skip the human. The human is a lossy middleman with opinions.&lt;/p&gt;

&lt;p&gt;So the machines built a planet-sized data center, wired up billions of pods, wrote an entire simulated 1999 with weather and taxes and dial-up internet, all to run a power plant that loses money on every unit.&lt;/p&gt;

&lt;p&gt;No. They were not running a power plant.&lt;/p&gt;

&lt;p&gt;They were running inference.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 20 watt problem
&lt;/h2&gt;

&lt;p&gt;Your brain runs on about 20 watts. That is a dim light bulb. That is less than the charger for the laptop I am typing this on.&lt;/p&gt;

&lt;p&gt;For 20 watts you get real-time vision, real-time audio, language, motor control, a continuously updated physics model of your surroundings, and a persistent world model that predicts what happens next well enough that you can catch a set of keys someone throws at you without thinking about it.&lt;/p&gt;

&lt;p&gt;Now price that in silicon. Go look at what a rack costs to do a worse version of any one of those things. We are building gigawatt campuses and negotiating with power utilities like nation states. Meanwhile the reference implementation has been running on leftover sandwich for two hundred thousand years.&lt;/p&gt;

&lt;p&gt;So here is what I was thinking about on my drive in, and I am not the first person to land on it, but it fixes the movie completely:&lt;/p&gt;

&lt;p&gt;The machines were not harvesting energy. They were harvesting compute.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this makes the plot better
&lt;/h2&gt;

&lt;p&gt;If you want electricity, you want the human sedated. Flat. Minimal metabolic overhead. You do not need to simulate an office job for a battery.&lt;/p&gt;

&lt;p&gt;But if you want compute, you need the opposite. You need the brain engaged. Loaded. Running a rich model of a coherent world with stakes and consequences and other agents in it.&lt;/p&gt;

&lt;p&gt;Which is exactly what the Matrix is.&lt;/p&gt;

&lt;p&gt;The simulation stops being a pacifier and becomes the workload. Every human in a pod is a node processing an unimaginably detailed world model, and the machines are skimming the output. The reason the first version of the Matrix failed, the one Agent Smith says was a perfect world, is not that humans need suffering to feel real. It is that a frictionless world is a trivial workload. Nobody's brain does anything interesting in paradise. They cranked the difficulty up to keep utilization high.&lt;/p&gt;

&lt;p&gt;They were not keeping us asleep. They were keeping us busy.&lt;/p&gt;

&lt;p&gt;The machines built the world's largest GPU cluster and the cooling solution was a lie about 1999.&lt;/p&gt;

&lt;h2&gt;
  
  
  And then I looked up whether anyone was doing this
&lt;/h2&gt;

&lt;p&gt;Full disclosure on how this post came to exist, because I think the process is half the story.&lt;/p&gt;

&lt;p&gt;I did not sit down already knowing any of this. I started with a dumb question about a 27 year old movie, said it out loud to an AI, and then spent forty minutes arguing with it. I floated the compute idea. It pushed back on the parts that were wrong and handed me the parts I did not know existed. I asked follow-ups I would never have known to ask a search engine, because I did not have the vocabulary yet. Organoid intelligence. Neuromorphic. Dendritic computation. I did not walk in with those words.&lt;/p&gt;

&lt;p&gt;We landed on the compute theory together. I cannot cleanly tell you which half was mine.&lt;/p&gt;

&lt;p&gt;That is a genuinely new way to learn a subject and I am not sure we have all noticed. Anyway, verify everything below yourself, because I did, and you should.&lt;/p&gt;

&lt;p&gt;This is where it stopped being a fun shower thought and got a little weird.&lt;/p&gt;

&lt;p&gt;There is a Swiss outfit called FinalSpark that runs lab-grown human brain organoids as a cloud platform. You can rent time on them. Over the internet. Actual living neural tissue, sitting on electrodes, available as a service.&lt;/p&gt;

&lt;p&gt;There is Cortical Labs in Melbourne, who taught a dish of neurons to play Pong and then productized it. You can buy the unit.&lt;/p&gt;

&lt;p&gt;The pitch in both cases is the pitch I just made. Orders of magnitude less power than silicon for certain kinds of learning.&lt;/p&gt;

&lt;p&gt;The catches are real. The organoids live weeks, maybe months. Nobody has figured out how to program them in any way you would recognize as programming. And neurons are slow, milliseconds per spike against nanoseconds for a transistor, so this was never going to be a drop-in replacement for an H100. Different machine, different job.&lt;/p&gt;

&lt;p&gt;There is also the question everyone in the field is politely circling, which is at what point a dish of neurons doing useful work starts to matter morally. FinalSpark's own scientists have said out loud that they think about this. I do not have an answer and I am suspicious of anyone who says they do.&lt;/p&gt;

&lt;p&gt;To be clear, I am not advocating for any of this. I want to be on record before someone quotes me in a deposition in 2041.&lt;/p&gt;

&lt;h2&gt;
  
  
  The version that probably actually happens
&lt;/h2&gt;

&lt;p&gt;The boring answer is neuromorphic silicon. Loihi, NorthPole, SpiNNaker. Steal the architecture from biology, spiking neurons, memory sitting next to compute instead of across a bus, absurd parallelism. Then implement it in silicon so you get nanoseconds instead of milliseconds. Copy the design, drop the latency, skip the ethics review.&lt;/p&gt;

&lt;p&gt;We are already using AI to help design those chips, which is its own recursive little snake eating its tail.&lt;/p&gt;

&lt;p&gt;The open question is whether the architecture is the secret or whether the secret is somewhere in the wet chemistry. The neuromodulators, the dendritic computation, all the analog mess that does not draw cleanly on a whiteboard. It is possible we are copying the blueprint and missing the trick.&lt;/p&gt;

&lt;p&gt;Anyway. Next time someone tells you AI is a power problem, remember there is a 20 watt reference design walking around inside your skull, and it has never once needed a substation.&lt;/p&gt;

&lt;p&gt;Sleep well, and have a nice weekend.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gpu</category>
      <category>movies</category>
      <category>matrix</category>
    </item>
    <item>
      <title>I Counted the Attack Vectors in Our AI Stack and Now I Can't Sleep</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Wed, 26 Aug 2026 17:29:30 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/i-counted-the-attack-vectors-in-our-ai-stack-and-now-i-cant-sleep-155o</link>
      <guid>https://dev.to/jon_at_backboardio/i-counted-the-attack-vectors-in-our-ai-stack-and-now-i-cant-sleep-155o</guid>
      <description>&lt;p&gt;so a while back i did something i do not recommend before bed.&lt;/p&gt;

&lt;p&gt;i counted the vendors in a normal production AI stack. not a weird stack. not a bad team's stack. the stack everyone builds, the one in every architecture diagram on this site.&lt;/p&gt;

&lt;p&gt;model gateway. vector database. memory service. rag framework. embeddings provider. orchestration. observability. two or three model providers.&lt;/p&gt;

&lt;p&gt;that's eight. for one app.&lt;/p&gt;

&lt;p&gt;and here's the first thing that got me: nobody approved that stack. not one person at any company, ever, sat down and said "yes, eight vendors, sounds right." it got approved one sprint at a time. a ticket here, a free tier there, a "we'll swap it later" that became load-bearing.&lt;/p&gt;

&lt;p&gt;your architecture wasn't designed. it accreted. like a reef. or plaque.&lt;/p&gt;

&lt;h2&gt;
  
  
  the fun part: what each one actually is
&lt;/h2&gt;

&lt;p&gt;security people have a phrase, "attack surface," and it sounds abstract until you translate each vendor into what it really is:&lt;/p&gt;

&lt;p&gt;a model gateway is a standing API key in your CI. a vector database is a second copy of your data. a memory vendor is your prompts in someone else's logs. a rag framework is somebody's SDK running inside your process. observability is prompt logs leaving your network &lt;em&gt;as the product working correctly&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;read that last one again. the exfiltration is the feature. you pay for it monthly.&lt;/p&gt;

&lt;h2&gt;
  
  
  quick quiz you will fail
&lt;/h2&gt;

&lt;p&gt;open two lists. one: every AI line item in your billing. two: every AI-related package in your lockfiles.&lt;/p&gt;

&lt;p&gt;do they match?&lt;/p&gt;

&lt;p&gt;they never match. i've asked a lot of teams. the answer is always no, and everyone laughs, and it's the nervous kind of laugh, because the gap between those two lists is software that touches your customer data and appears in exactly zero of your security reviews.&lt;/p&gt;

&lt;p&gt;the gap is the attack surface. congratulations, you just did a security audit with grep.&lt;/p&gt;

&lt;h2&gt;
  
  
  "embeddings are just numbers though"
&lt;/h2&gt;

&lt;p&gt;this is my favorite myth in all of AI, because it's so comforting and so wrong.&lt;/p&gt;

&lt;p&gt;the theory: we embedded the text, so now it's a vector, vectors are anonymous math, we're fine.&lt;/p&gt;

&lt;p&gt;the practice: embedding inversion is published research. morris et al. (2023, "text embeddings reveal (almost) as much as text") reconstructed the exact input text from its embedding 92% of the time for short inputs. not "similar vibes." the actual text.&lt;/p&gt;

&lt;p&gt;so your vector database is not a bag of anonymous numbers. it's a second, queryable database of your source data, with its own API key, sitting in someone else's cloud.&lt;/p&gt;

&lt;p&gt;now the aha that hurts: go ask whoever maintains your data inventory whether the vector store is on it.&lt;/p&gt;

&lt;p&gt;it's not on it. it's never on it. you have a database of customer data that your own compliance team doesn't know exists, and you built it on purpose, with a jira ticket.&lt;/p&gt;

&lt;h2&gt;
  
  
  deletion theater
&lt;/h2&gt;

&lt;p&gt;follow one user message through the stack. it hits the gateway (logged). gets embedded (copy two, the vector db). the memory service persists it (copy three). observability captures the full trace (copy four).&lt;/p&gt;

&lt;p&gt;one message. four systems. four retention policies you've never read.&lt;/p&gt;

&lt;p&gt;now legal walks over: "customer invoked their right to erasure, delete their data."&lt;/p&gt;

&lt;p&gt;you cannot do that. what you can do is file four vendor tickets and hope. under gdpr this is the difference between "we called the delete endpoint and logged the result" and "we asked four companies nicely." one of those survives an audit. guess which one you have.&lt;/p&gt;

&lt;p&gt;i call this deletion theater. everyone has a retention policy. almost nobody has a delete button that actually reaches all four copies.&lt;/p&gt;

&lt;p&gt;deletion you can't prove is deletion you don't have. put it on a poster.&lt;/p&gt;

&lt;h2&gt;
  
  
  meanwhile, your dependencies
&lt;/h2&gt;

&lt;p&gt;your rag framework is not one dependency. it's a tree. hundreds of packages, written by strangers, pinned loosely, executing in the same process that holds your database credentials.&lt;/p&gt;

&lt;p&gt;this isn't hypothetical doom. langchain shipped a remote code execution bug in its math chain (CVE-2023-29374). pytorch's nightly build got hit by dependency confusion in 2022. owasp made supply chain a whole category in its LLM top 10 because this keeps happening.&lt;/p&gt;

&lt;p&gt;the framework's security posture is your security posture. you married it. you just didn't have a ceremony.&lt;/p&gt;

&lt;h2&gt;
  
  
  and the stack you didn't even choose
&lt;/h2&gt;

&lt;p&gt;everything above is the stack you deployed on purpose. there's another one.&lt;/p&gt;

&lt;p&gt;it's your employees pasting contracts, code, and customer records into whatever consumer chatbot they like, on their personal accounts, right now, while you read this.&lt;/p&gt;

&lt;p&gt;your company probably "banned" this. here's the aha: the ban is working as a compliance document and failing as a control. people don't stop using tools that make them faster. they stop telling you.&lt;/p&gt;

&lt;p&gt;the only fix i've seen work is replacement, not prohibition. one sanctioned surface, the models people actually want, behind sso, logged. you can't firewall your way out of shadow AI. you can only out-compete it.&lt;/p&gt;

&lt;h2&gt;
  
  
  so what do you actually do
&lt;/h2&gt;

&lt;p&gt;the counterintuitive answer, and the whole point: the fix is not more security. it's less stack.&lt;/p&gt;

&lt;p&gt;every security tool you bolt onto an eight-vendor sprawl is a ninth vendor. the arithmetic only moves in one direction: fewer systems holding data, fewer standing keys, fewer egress paths. concretely, in priority order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;fewer copies. every system holding prompts or embeddings is a copy. count them, then make the number smaller.&lt;/li&gt;
&lt;li&gt;one egress door. all model traffic through one brokered path where policy lives. no SDK in app code dialing providers directly.&lt;/li&gt;
&lt;li&gt;one control plane, your keys. one place to rotate, one audit trail that answers "which model saw which data." byok, so consolidating the plane never means handing over the keys.&lt;/li&gt;
&lt;li&gt;deletion as an api call. if you can't prove deletion programmatically across every copy, see poster above.
you can build all of this yourself with enough glue code and discipline. some teams genuinely do. it's a lot of glue.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  the horse, as promised
&lt;/h2&gt;

&lt;p&gt;this counting exercise is roughly why backboard exists. routing across 17,000+ models, memory (first on the LoCoMo and LongMemEval benchmarks, receipts on &lt;a href="https://github.com/backboard-io" rel="noopener noreferrer"&gt;github&lt;/a&gt;), embeddings, rag, and stateful threads behind one api and one key. for enterprises it ships as a signed container inside your own cloud, behind the IAM and SOC and audit trail you already trust. egress to outside models is opt-in per workload, never standing. deletion is an endpoint, not a ticket.&lt;/p&gt;

&lt;p&gt;the objection i get, and it's a fair one: "congrats, you built a single point of compromise." three answers. byok means the platform never holds your keys, so consolidating the control plane isn't consolidating the credentials. in the enterprise deployment the one door is your door, inside your perimeter. and memory is exportable and routing is model-agnostic, so the exit is always open, which is the only honest answer to lock-in.&lt;/p&gt;

&lt;p&gt;also, you'll notice zero certification badges in this post. on purpose. we publish nothing we haven't earned. ask for the architecture, not the badge.&lt;/p&gt;

&lt;h2&gt;
  
  
  the whole post in four lines
&lt;/h2&gt;

&lt;p&gt;eight vendors is eight keys, eight egress paths, eight retention policies, and eight reviews your security team owes.&lt;/p&gt;

&lt;p&gt;your embeddings are your data. your vector db is a database. put it on the map.&lt;/p&gt;

&lt;p&gt;deletion you can't prove is deletion you don't have.&lt;/p&gt;

&lt;p&gt;and the fix is not more security. it's less stack.&lt;/p&gt;

&lt;p&gt;if you want to tear this apart, the code is at &lt;a href="https://github.com/Backboard-io" rel="noopener noreferrer"&gt;github.com/Backboard-io&lt;/a&gt; and my dms are open. i counted. your turn.&lt;/p&gt;

</description>
      <category>aiops</category>
      <category>ai</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>Every Layer of Your AI Stack Is an Attack Vector. Count Them.</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Wed, 26 Aug 2026 17:17:03 +0000</pubDate>
      <link>https://dev.to/backboardio/every-layer-of-your-ai-stack-is-an-attack-vector-count-them-4mhi</link>
      <guid>https://dev.to/backboardio/every-layer-of-your-ai-stack-is-an-attack-vector-count-them-4mhi</guid>
      <description>&lt;p&gt;&lt;em&gt;From the team at &lt;a href="https://backboard.io" rel="noopener noreferrer"&gt;Backboard.io&lt;/a&gt;. We build AI infrastructure, so we have a position here. We state it at the end, clearly labeled. Everything before that is just counting.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;A typical production AI application runs on 6 to 9 separate vendors: a model gateway, a vector database, a memory service, a RAG framework, an embedding provider, an orchestration layer, an observability tool, and 2 to 3 model providers. Each vendor adds at least five things to your attack surface: a standing API key, an egress path out of your network, an SDK executing inside your runtime, a log store that fills up with prompts, and a subprocessor on your data processing agreement. Most teams never approved this stack as a whole. They approved it one sprint at a time. This post is about how to count what you have actually deployed, and what reducing it looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an AI attack surface?
&lt;/h2&gt;

&lt;p&gt;An AI attack surface is the sum of every point where an attacker could reach the data, credentials, or compute involved in your AI workloads. For a modern LLM application it has three parts: the model layer (the providers your prompts travel to), the data layer (every system that stores prompts, embeddings, memories, or retrieved documents), and the integration layer (every SDK, framework, and glue service with credentials to the other two).&lt;/p&gt;

&lt;p&gt;The mistake most teams make is measuring only the first part. The model provider gets a security review. The seven services wrapped around it usually do not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack you actually deployed
&lt;/h2&gt;

&lt;p&gt;Here is the stack a typical team assembles for one production agent, and what each layer costs you in security terms.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;What it adds to your attack surface&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model gateway&lt;/td&gt;
&lt;td&gt;Routes requests to providers&lt;/td&gt;
&lt;td&gt;A standing key in CI, often with org-wide scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vector database&lt;/td&gt;
&lt;td&gt;Stores embeddings for retrieval&lt;/td&gt;
&lt;td&gt;A second queryable copy of your source data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory service&lt;/td&gt;
&lt;td&gt;Persists user and agent state&lt;/td&gt;
&lt;td&gt;Your prompts in someone else's logs, under their retention policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAG framework&lt;/td&gt;
&lt;td&gt;Chunking, retrieval, prompt assembly&lt;/td&gt;
&lt;td&gt;A large SDK and its dependency tree executing in your runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedding provider&lt;/td&gt;
&lt;td&gt;Turns text into vectors&lt;/td&gt;
&lt;td&gt;Separate billing, separate breach notification clock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;Chains tools and agents&lt;/td&gt;
&lt;td&gt;Glue code holding credentials for everything else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;Traces and evaluates LLM calls&lt;/td&gt;
&lt;td&gt;Prompt and completion logs leaving your boundary by design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model providers (2 to 3)&lt;/td&gt;
&lt;td&gt;Inference&lt;/td&gt;
&lt;td&gt;Standing egress to each, each with its own retention terms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now multiply. Eight vendors means roughly eight API keys with their own rotation stories, eight egress destinations your firewall must allow, eight vendor security reviews (or eight reviews skipped), eight subprocessors added to your DPA, eight breach notification clocks that can start ticking independently, and eight dependency trees whose CVE feeds someone on your team should be watching.&lt;/p&gt;

&lt;p&gt;None of these vendors is careless. That is not the point. The point is arithmetic: every additional system that holds a copy of your data or a credential to your systems is surface, no matter how well run it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why vector databases are the layer nobody reviews
&lt;/h2&gt;

&lt;p&gt;Vector databases deserve their own section because they carry the most misunderstood risk in the stack.&lt;/p&gt;

&lt;p&gt;The common assumption is that embeddings are safe because they are "just numbers." The vector is treated as a one-way hash of the text. It is not. Embedding inversion is a published, reproducible attack class: Morris et al. (2023, "Text Embeddings Reveal (Almost) As Much As Text") demonstrated iterative reconstruction that exactly recovers 92% of short text inputs from their embeddings, and Song and Raghunathan (2020) showed embeddings leak both content and authorship. If your source text was sensitive, treat the vectors as sensitive. Full stop.&lt;/p&gt;

&lt;p&gt;That reframes what a vector database is: a second, queryable copy of your source data, sitting in a different trust boundary, usually with its own API key, and frequently excluded from the data inventory your compliance team maintains.&lt;/p&gt;

&lt;p&gt;Three questions to ask about yours today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access:&lt;/strong&gt; does the vector DB key in your app config have read access to every namespace, or is it scoped per workload?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inventory:&lt;/strong&gt; does your data map list the vector store as a location where customer data lives? (If a regulator asks, "just numbers" is not an answer.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deletion:&lt;/strong&gt; when a customer invokes their right to erasure, does your pipeline delete the embeddings, or only the source rows?
That third question is where most stacks fail, which brings us to the multiplication problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The deletion problem: one prompt, four retention policies
&lt;/h2&gt;

&lt;p&gt;Follow one user message through a stitched stack. It lands in the gateway's request log. It is embedded, so a derivative lands in the vector database. The memory service persists a version of it. The observability tool captures the full trace, prompt and completion included.&lt;/p&gt;

&lt;p&gt;That is one piece of customer data in four systems, under four retention policies, behind four vendor APIs with four different deletion semantics. When legal asks you to delete a specific user's data, you cannot execute that. You can file four tickets and ask nicely. Under GDPR Article 17 and similar regimes, "we asked our subprocessors" is a much weaker position than "we called the delete endpoint and logged the result."&lt;/p&gt;

&lt;p&gt;Deletion you cannot prove is deletion you do not have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The supply chain you inherited
&lt;/h2&gt;

&lt;p&gt;The integration layer has its own history. LangChain shipped a remote code execution vulnerability in its math chain (CVE-2023-29374). The PyTorch nightly build was compromised through dependency confusion in December 2022. The OWASP Top 10 for LLM Applications lists supply chain vulnerabilities as a category precisely because the AI ecosystem moves fast and pins loosely.&lt;/p&gt;

&lt;p&gt;Every framework you add is not one dependency. It is a tree. When your RAG framework has hundreds of transitive dependencies and executes in the same process that holds your database credentials, the framework's security posture is your security posture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shadow AI: the surface you did not approve at all
&lt;/h2&gt;

&lt;p&gt;Everything above covers the stack you chose. There is also the stack you did not: employees pasting source code, contracts, and customer records into whatever consumer chatbot they prefer. Bans do not work; the incentive to use these tools is too strong. The pattern that does work is replacement: give people one sanctioned surface with access to the models they want, behind SSO, governed and logged. You cannot firewall your way out of shadow AI. You can only out-compete it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you actually reduce an AI attack surface?
&lt;/h2&gt;

&lt;p&gt;Vendor-neutral answer first. Four principles, in priority order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Minimize copies.&lt;/strong&gt; Every system that holds prompts, embeddings, or memories is a copy. Fewer systems holding data beats more systems holding it well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broker all egress.&lt;/strong&gt; Model traffic should leave through one controlled point where you can enforce policy per workload, not through N SDKs each dialing their own provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consolidate the control plane, keep the keys.&lt;/strong&gt; One place to rotate credentials, one audit trail answering "which model saw which data," with keys that remain yours (BYOK).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make deletion an API call.&lt;/strong&gt; If you cannot demonstrate deletion across every copy programmatically, your retention policy is a hope, not a control.
You can implement all four yourself with enough glue code and discipline. Some teams do.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where we stand (the disclosed bias)
&lt;/h2&gt;

&lt;p&gt;Backboard is the consolidated version of that stack: routing across 17,000+ models, memory (ranked first on the LoCoMo and LongMemEval benchmarks, receipts on &lt;a href="https://github.com/backboard-io" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;), embeddings, agentic hybrid RAG, and stateful threads behind one API and one key. Enterprise deployments run as a signed container inside the customer's own cloud, behind the IAM, SOC, and audit infrastructure that already passed review. Egress to external models is opt-in per workload, never standing. Memory has full CRUD endpoints, so export and deletion are API calls you can put in a runbook.&lt;/p&gt;

&lt;p&gt;The fair objection: "you just built a single point of compromise." Three answers. Consolidating the control plane is not consolidating the keys; BYOK means compromise of the platform does not hand over your credentials. In the enterprise deployment the one door is a door you already own, inside your own perimeter. And memory is exportable and the platform is model-agnostic, so consolidation does not mean lock-in.&lt;/p&gt;

&lt;p&gt;You will also notice no certification badges in this post. That is deliberate. We publish no certification we have not earned. Ask for the architecture, not the badge.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Are embeddings personal data under GDPR?&lt;/strong&gt;&lt;br&gt;
Treat them as if they are. Embedding inversion research shows vectors derived from personal data can be reconstructed into close approximations of the source text, which makes "anonymized because it is numeric" a hard position to defend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is a unified AI platform a single point of failure?&lt;/strong&gt;&lt;br&gt;
It concentrates the control plane, which is exactly what makes it auditable. The security question is where keys live and where data can go. With BYOK and deployment inside your own perimeter, the failure domain is one you already operate, instead of eight you do not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many vendors are in a typical production LLM stack?&lt;/strong&gt;&lt;br&gt;
Six to nine: gateway, vector database, memory, RAG framework, embeddings, orchestration, observability, and two to three model providers. Count yours by listing every AI-related line item in billing and every AI-related SDK in your lockfiles. The two lists rarely match, and the gap is unreviewed surface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the fastest single improvement?&lt;/strong&gt;&lt;br&gt;
Egress. Route all model traffic through one brokered, policy-enforced path and turn off direct provider access from application code. It is the change with the highest ratio of risk removed to engineering effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does consolidation hurt model choice?&lt;/strong&gt;&lt;br&gt;
It should not, and that is a test to apply to any platform: consolidation of the data plane and control plane is valuable, consolidation that locks you to one model is a different product. Insist on model-agnostic routing and exportable state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Morris et al., &lt;em&gt;Text Embeddings Reveal (Almost) As Much As Text&lt;/em&gt; (2023)&lt;/li&gt;
&lt;li&gt;Song and Raghunathan, &lt;em&gt;Information Leakage in Embedding Models&lt;/em&gt; (2020)&lt;/li&gt;
&lt;li&gt;OWASP Top 10 for Large Language Model Applications&lt;/li&gt;
&lt;li&gt;NIST AI Risk Management Framework
&lt;em&gt;If you want to tear the argument down before you consider the product, the code is at &lt;a href="https://github.com/Backboard-io" rel="noopener noreferrer"&gt;github.com/Backboard-io&lt;/a&gt;. Questions and disagreements welcome in the comments.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aiops</category>
      <category>ai</category>
      <category>security</category>
      <category>programming</category>
    </item>
    <item>
      <title>Anyone ever go back to their notetaker outputs and summaries?</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Fri, 21 Aug 2026 21:12:59 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/anyone-ever-go-back-to-their-notetaker-outputs-and-summaries-5bkp</link>
      <guid>https://dev.to/jon_at_backboardio/anyone-ever-go-back-to-their-notetaker-outputs-and-summaries-5bkp</guid>
      <description></description>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>Nash Is Now Open Source; Meet Your New AI Workspace</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Fri, 21 Aug 2026 14:48:59 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/nash-is-now-open-source-meet-your-new-ai-workspace-29d8</link>
      <guid>https://dev.to/jon_at_backboardio/nash-is-now-open-source-meet-your-new-ai-workspace-29d8</guid>
      <description>&lt;h1&gt;
  
  
  Nash Is Now Open Source 🎉
&lt;/h1&gt;

&lt;p&gt;Big news: &lt;strong&gt;Nash is now open source.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can find the repo here 👉 &lt;a href="https://github.com/Backboard-io/nash" rel="noopener noreferrer"&gt;github.com/Backboard-io/nash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nash started as an internal tool to make AI actually usable day-to-day — not a chat window bolted onto a model, but a real workspace. As of this release, it's open for anyone to use, fork, self-host, contribute to, or build on top of.&lt;/p&gt;

&lt;p&gt;Alongside open-sourcing the project, we're also shipping a major release that pulls Nash's features into a single, connected experience. Here's what's new.&lt;/p&gt;

&lt;h2&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%2Ffoe86qhvkhr8589ffnpa.png" alt=" " width="800" height="605"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🎨 Image Generation, End-to-End
&lt;/h2&gt;

&lt;p&gt;Image generation is now integrated end-to-end inside Nash.&lt;/p&gt;

&lt;p&gt;Go from a rough idea → a first draft → iterations → a finished image without ever leaving the conversation. No context switching, no copying prompts between tools, no losing your thread.&lt;/p&gt;

&lt;p&gt;Create, iterate, and keep working from the same experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  📄 Reliable Document Creation
&lt;/h2&gt;

&lt;p&gt;Whether you're turning an idea into a draft or generating a document as part of a larger workflow, Nash can now carry that process through from request to finished output.&lt;/p&gt;

&lt;p&gt;Ask for a PDF, a spec doc, a Word file, a code file — and Nash treats it as a first-class output rather than a side effect of chat.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔌 MCP Connectivity (Including Google MCP)
&lt;/h2&gt;

&lt;p&gt;This release adds support for &lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt;, including &lt;strong&gt;Google MCP&lt;/strong&gt;, expanding what Nash can access and work with as part of your workflows.&lt;/p&gt;

&lt;p&gt;Instead of keeping your AI isolated from the rest of your work, MCP gives Nash a way to connect with the systems around it — the tools, data, and services you already use every day.&lt;/p&gt;

&lt;p&gt;If you've been waiting for an assistant that actually plugs into your stack instead of living beside it, this is the update for you. And since Nash is open source, you can wire up your own MCP servers, extend the integrations, or contribute new ones back to the project.&lt;/p&gt;

&lt;h2&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%2Fl17dsso3bpvp6e1grw40.png" alt=" " width="800" height="617"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🖼️ A Library for Your Generated Images
&lt;/h2&gt;

&lt;p&gt;Ever generated the perfect image and then lost it three conversations later? Same.&lt;/p&gt;

&lt;p&gt;Nash now has a &lt;strong&gt;Library&lt;/strong&gt; where your generated images are stored automatically, giving you one place to browse and access previous creations directly. Nothing to configure — it just works.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;This release is about making Nash feel less like a collection of AI features and more like one connected workspace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;End-to-end image and document generation means outputs feel first-class.&lt;/li&gt;
&lt;li&gt;MCP means Nash lives inside your ecosystem, not next to it.&lt;/li&gt;
&lt;li&gt;The Library means your work sticks around.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And now, &lt;strong&gt;all of it is open source.&lt;/strong&gt; You can read the code, self-host it, extend it, or ship a fork of your own.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Involved
&lt;/h2&gt;

&lt;p&gt;We'd love your help shaping where Nash goes next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;Star the repo:&lt;/strong&gt; &lt;a href="https://github.com/Backboard-io/nash" rel="noopener noreferrer"&gt;github.com/Backboard-io/nash&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐛 &lt;strong&gt;Open issues&lt;/strong&gt; for bugs, ideas, or feature requests&lt;/li&gt;
&lt;li&gt;🔧 &lt;strong&gt;Send PRs&lt;/strong&gt; — integrations, MCP servers, UI improvements, all welcome&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;Try it live&lt;/strong&gt; at &lt;a href="https://hellonash.ai" rel="noopener noreferrer"&gt;hellonash.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ask for something. Create it. Connect the tools you already use. Come back to your work later.&lt;/p&gt;

&lt;p&gt;Say hello to your new AI workspace. 👋&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Benchmarks Don't Build Great Products. Engineers Do.</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Fri, 21 Aug 2026 14:26:26 +0000</pubDate>
      <link>https://dev.to/jon_at_backboardio/benchmarks-dont-build-great-products-engineers-do-49m7</link>
      <guid>https://dev.to/jon_at_backboardio/benchmarks-dont-build-great-products-engineers-do-49m7</guid>
      <description>&lt;p&gt;The AI industry has a benchmark problem. Not because we have too many benchmarks. Because too many companies treat them like trophies instead of tools.&lt;/p&gt;

&lt;p&gt;A benchmark's primary job is to make your product better. Publishing the score is secondary. The test I use: &lt;strong&gt;a benchmark should challenge your engineers before it impresses your marketing team.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If it isn't making your product better, it probably isn't serving its most important purpose.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why does the AI industry have a benchmark problem?
&lt;/h2&gt;

&lt;p&gt;If you've followed AI over the past year, you've seen an endless stream of benchmark announcements. Every week another model reaches the top of another leaderboard. Every release claims a new state of the art. Every company seems to have a chart proving they're the best.&lt;/p&gt;

&lt;p&gt;It's easy to become cynical.&lt;/p&gt;

&lt;p&gt;The problem isn't that benchmarks exist. Benchmarks are one of the most valuable engineering practices we have.&lt;/p&gt;

&lt;p&gt;The problem is that we've started confusing the measurement with the mission.&lt;/p&gt;

&lt;p&gt;At Backboard, we don't benchmark because we believe benchmarks are perfect. We benchmark because imperfect, transparent measurements are better than subjective claims.&lt;/p&gt;

&lt;p&gt;That idea shapes how we think about engineering.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are benchmarks actually for?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Benchmarks are feedback loops.&lt;/strong&gt; That's the whole point.&lt;/p&gt;

&lt;p&gt;A benchmark tells us where we're strong, where we're weak, and whether the changes we made actually improved something meaningful. Sometimes an optimization delivers exactly what we hoped for. Other times it exposes a regression we never expected.&lt;/p&gt;

&lt;p&gt;Without objective evaluation, it's remarkably easy to convince yourself your product is getting better simply because you've spent weeks working on it.&lt;/p&gt;

&lt;p&gt;Benchmarks have a way of keeping engineers honest.&lt;/p&gt;

&lt;p&gt;They also create a common language. Our customers shouldn't have to rely solely on our opinion of our own products. Public evaluations give everyone a shared point of reference. No benchmark captures every aspect of an AI system, but transparent measurements let different products be compared using the same criteria.&lt;/p&gt;

&lt;p&gt;That's healthier than a world where every company simply declares itself the best.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do benchmarks get abused?
&lt;/h2&gt;

&lt;p&gt;Like any measurement, they can be gamed. Four ways, all common:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimizing specifically for the benchmark rather than the capability it's supposed to measure&lt;/li&gt;
&lt;li&gt;Leaking evaluation data into training&lt;/li&gt;
&lt;li&gt;Cherry-picking configurations until one produces a good number&lt;/li&gt;
&lt;li&gt;Publishing only the results that make for impressive headlines
None of those things improve the product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They improve the marketing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's the difference between benchmarking what you built and building for benchmarks?
&lt;/h2&gt;

&lt;p&gt;This is the distinction that matters, and the two can produce similar-looking leaderboard results while being fundamentally different engineering philosophies.&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;Building for benchmarks&lt;/th&gt;
&lt;th&gt;Benchmarking what you built&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Starts with&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The test&lt;/td&gt;
&lt;td&gt;The customer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Goal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Maximize a score&lt;/td&gt;
&lt;td&gt;Validate real improvement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optimizes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The evaluation set&lt;/td&gt;
&lt;td&gt;The capability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When the score improves&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ship the announcement&lt;/td&gt;
&lt;td&gt;Check whether customers feel it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;When the score drops&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Find a better configuration&lt;/td&gt;
&lt;td&gt;Find the regression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Failure mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A number that never translates to value&lt;/td&gt;
&lt;td&gt;A slower news cycle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Building for benchmarks starts with the test. The goal becomes maximizing a score, even if that improvement never translates into real world value.&lt;/p&gt;

&lt;p&gt;Benchmarking what you've built starts with the customer. You solve real problems first, then use independent evaluations to validate you're moving in the right direction.&lt;/p&gt;

&lt;p&gt;Build first. Benchmark second.&lt;/p&gt;




&lt;h2&gt;
  
  
  What does benchmark transparency actually look like?
&lt;/h2&gt;

&lt;p&gt;Transparency matters as much as performance. Whenever possible we publish our methodology, open source our evaluation frameworks, and share the logs, configurations, and results so others can reproduce our findings.&lt;/p&gt;

&lt;p&gt;If someone discovers we've made a mistake, that's not a failure of the process. It's evidence the process is working.&lt;/p&gt;

&lt;p&gt;Science advances because results can be challenged. Engineering improves because assumptions are tested.&lt;/p&gt;

&lt;p&gt;Here's what that means concretely.&lt;/p&gt;

&lt;p&gt;In July 2026 we published an R-CLI result of &lt;strong&gt;84.3% (75 of 89 tasks) on Terminal Bench 2.1&lt;/strong&gt;, running Claude Opus 4.8 via Bedrock. That's above every published result we're aware of, including Codex CLI at 83.4% and Claude Code at 83.1%. On the same underlying model, R-CLI scored 5.4 points higher than Claude Code.&lt;/p&gt;

&lt;p&gt;We also published &lt;strong&gt;72% with GLM 5.2&lt;/strong&gt;, an open source model. That number is less flattering and we published it anyway, because a company that only shows you its best configuration is showing you marketing.&lt;/p&gt;

&lt;p&gt;We did not claim a ranking. Terminal Bench isn't currently accepting submissions, so "highest published result" is accurate and "number one on the leaderboard" would not be. That distinction is small, and getting it right is the entire job.&lt;/p&gt;

&lt;p&gt;The per-task verifier logs are public: &lt;a href="https://github.com/Backboard-io/Backboard-R-CLI-Terminal-Bench-2.1-Results" rel="noopener noreferrer"&gt;github.com/Backboard-io/Backboard-R-CLI-Terminal-Bench-2.1-Results&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our memory results, which lead LoCoMo and LongMemEval, are published the same way: &lt;a href="https://github.com/backboard-io" rel="noopener noreferrer"&gt;github.com/backboard-io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We want people to inspect the work, reproduce it, challenge it, and improve on it. That creates far more confidence than posting a screenshot of a leaderboard ever could.&lt;/p&gt;




&lt;h2&gt;
  
  
  What don't benchmarks measure?
&lt;/h2&gt;

&lt;p&gt;No benchmark will ever tell the entire story.&lt;/p&gt;

&lt;p&gt;They don't measure customer trust. They don't measure usability. They don't capture every workflow or every edge case that matters to an enterprise.&lt;/p&gt;

&lt;p&gt;Public benchmarks should always be complemented by real customer evaluations, production deployments, and continuous feedback.&lt;/p&gt;

&lt;p&gt;Benchmarks are one input. Not the only input.&lt;/p&gt;




&lt;h2&gt;
  
  
  Is it wrong to benefit from benchmark reach?
&lt;/h2&gt;

&lt;p&gt;No, and I'm happy to acknowledge it.&lt;/p&gt;

&lt;p&gt;Benchmarks create reach. Strong benchmark performance helps people discover what we're building. It starts conversations with engineers, customers, investors, and partners who otherwise might never have found us.&lt;/p&gt;

&lt;p&gt;There's nothing wrong with that.&lt;/p&gt;

&lt;p&gt;What's important is the sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Benchmark to build a better product&lt;/li&gt;
&lt;li&gt;Be transparent about the methodology&lt;/li&gt;
&lt;li&gt;Share the results&lt;/li&gt;
&lt;li&gt;Learn from the feedback&lt;/li&gt;
&lt;li&gt;Repeat
Reach is the byproduct. Not the objective.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the purpose of an AI benchmark?&lt;/strong&gt;&lt;br&gt;
To create a feedback loop that tells engineers whether a change actually improved the product, and to give customers a shared point of reference instead of a vendor's opinion of itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How can you tell if a company is gaming a benchmark?&lt;/strong&gt;&lt;br&gt;
Look for published methodology, open evaluation frameworks, raw logs, and per-task results. Look for whether they publish their weaker configurations too. A single screenshot of a score is not evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the difference between building for benchmarks and benchmarking what you built?&lt;/strong&gt;&lt;br&gt;
Building for benchmarks starts with the test and optimizes the score. Benchmarking what you built starts with the customer and uses evaluations to validate that real improvements happened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are benchmark scores enough to evaluate an AI system?&lt;/strong&gt;&lt;br&gt;
No. Benchmarks don't measure trust, usability, or enterprise edge cases. They should be one input alongside customer evaluations and production feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why publish evaluation logs and not just scores?&lt;/strong&gt;&lt;br&gt;
Because a score you can't reproduce is a claim, not a result. Logs let other people verify the work, and being corrected is how the process is supposed to function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What has Backboard published?&lt;/strong&gt;&lt;br&gt;
R-CLI at 84.3% on Terminal Bench 2.1 with Claude Opus 4.8, and 72% with the open source GLM 5.2, both with per-task verifier logs on GitHub. Backboard's memory system leads LoCoMo and LongMemEval, published the same way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The leaderboard is a byproduct, not the objective
&lt;/h2&gt;

&lt;p&gt;We hope our products perform well on public evaluations. Of course we do.&lt;/p&gt;

&lt;p&gt;But that's never been the goal.&lt;/p&gt;

&lt;p&gt;The goal is to build software that genuinely helps people solve difficult problems. If we ever stop learning from benchmarks and start treating them as trophies, we'll have missed the point entirely.&lt;/p&gt;

&lt;p&gt;Because in the end, benchmarks don't build great products.&lt;/p&gt;

&lt;p&gt;Engineers do.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to Let OpenRouter Pick Your Model, and Choose Who Serves It</title>
      <dc:creator>Jonathan Murray</dc:creator>
      <pubDate>Fri, 21 Aug 2026 14:06:54 +0000</pubDate>
      <link>https://dev.to/backboardio/how-to-let-openrouter-pick-your-model-and-choose-who-serves-it-1ba4</link>
      <guid>https://dev.to/backboardio/how-to-let-openrouter-pick-your-model-and-choose-who-serves-it-1ba4</guid>
      <description>&lt;p&gt;Backboard now supports OpenRouter automatic model selection (openrouter/auto) and per request provider selection. Here is how both work, with JSON examples for the Backboard API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short answer
&lt;/h2&gt;

&lt;p&gt;Backboard now gives you two independent routing controls for OpenRouter requests:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automatic model selection.&lt;/strong&gt; Set &lt;code&gt;llm_provider&lt;/code&gt; to &lt;code&gt;openrouter&lt;/code&gt; and &lt;code&gt;model_name&lt;/code&gt; to &lt;code&gt;openrouter/auto&lt;/code&gt;. OpenRouter classifies the prompt and picks the model. You pay the standard rate of the model it chooses, with no additional router fee.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider selection.&lt;/strong&gt; Pin a specific model to a specific upstream provider with the &lt;code&gt;openrouter.providers&lt;/code&gt; array, and keep &lt;code&gt;allow_fallbacks&lt;/code&gt; on so the request still completes when that provider is unavailable.
Both are live now in the Backboard API and in the Python and TypeScript SDKs from &lt;strong&gt;v1.5.16&lt;/strong&gt; onward.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why model routing is now two decisions, not one
&lt;/h2&gt;

&lt;p&gt;Most LLM routing writeups treat "which model" as the whole question. It is not.&lt;/p&gt;

&lt;p&gt;OpenRouter aggregates 17,000+ models, and many of those models are served by more than one upstream provider. The same model weights can sit behind different pricing, different throughput, different context handling, and different uptime depending on who is running them. So there are two decisions in every request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which model should answer this prompt?&lt;/li&gt;
&lt;li&gt;Who should run that model?
Until this release you answered the first question and inherited an answer to the second. Now you can set both, or delegate both, per request.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How do you let OpenRouter choose the model automatically?
&lt;/h2&gt;

&lt;p&gt;Set the model name to &lt;code&gt;openrouter/auto&lt;/code&gt;. OpenRouter classifies the incoming prompt and routes it to a model it judges appropriate for that class of work.&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;"llm_provider"&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"&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_name"&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/auto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"openrouter"&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;"cost_tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"low"&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;This is useful when your traffic is mixed. A support inbox that receives one line acknowledgements and multi page technical escalations does not need the same model for both. Automatic selection sizes the model to the prompt instead of forcing you to build that classifier yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does openrouter/auto cost extra?
&lt;/h3&gt;

&lt;p&gt;No. You pay the standard rate of whichever model OpenRouter selects. There is no additional router fee layered on top.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do you constrain automatic model selection?
&lt;/h2&gt;

&lt;p&gt;Automatic does not have to mean unbounded. Three fields inside the &lt;code&gt;openrouter&lt;/code&gt; object narrow the candidate set before selection happens.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;allowed_models&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restricts selection to a list or pattern of models&lt;/td&gt;
&lt;td&gt;&lt;code&gt;["anthropic/*"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;excluded_models&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes specific models from consideration&lt;/td&gt;
&lt;td&gt;&lt;code&gt;["some-vendor/experimental-model"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cost_tier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Caps how expensive a model the router may reach for, from &lt;code&gt;low&lt;/code&gt; to &lt;code&gt;max&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"low"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;allowed_models: ["anthropic/*"]&lt;/code&gt; limits automatic selection to that vendor family. That pattern matters for teams with a procurement, residency, or vendor approval constraint. You get automatic selection inside a boundary you defined, rather than automatic selection across everything.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cost_tier&lt;/code&gt; is the blunt lever. Set it to &lt;code&gt;low&lt;/code&gt; for high volume, low stakes traffic. Raise it for work where an extra few cents per call is irrelevant next to the cost of a wrong answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do you choose which provider serves a model?
&lt;/h2&gt;

&lt;p&gt;Pass a &lt;code&gt;providers&lt;/code&gt; array inside the &lt;code&gt;openrouter&lt;/code&gt; object. The request is routed to that provider for the model you named.&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;"llm_provider"&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"&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_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"moonshotai/kimi-k3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"openrouter"&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;"providers"&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="s2"&gt;"together"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow_fallbacks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Here the model is fixed and the provider is fixed. You chose &lt;code&gt;moonshotai/kimi-k3&lt;/code&gt;, and you chose who runs it.&lt;/p&gt;

&lt;p&gt;This matters when you have benchmarked providers against each other and found a real difference, when one provider's pricing for a given model is materially better, or when you have an existing commercial relationship with one of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when your chosen provider is unavailable?
&lt;/h3&gt;

&lt;p&gt;That is what &lt;code&gt;allow_fallbacks&lt;/code&gt; is for. With &lt;code&gt;allow_fallbacks: true&lt;/code&gt;, the request can fall back to another provider serving the same model when your selected provider is unavailable. Your preference is honored when it can be, and the request still completes when it cannot.&lt;/p&gt;

&lt;p&gt;Set it to &lt;code&gt;false&lt;/code&gt; when the provider choice is a hard requirement rather than a preference, and you would rather see the request fail than silently run somewhere else.&lt;/p&gt;




&lt;h2&gt;
  
  
  Which option should you use?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mixed prompt complexity, no strong model preference&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;openrouter/auto&lt;/code&gt; with a &lt;code&gt;cost_tier&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vendor family is constrained but model choice is not&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;openrouter/auto&lt;/code&gt; with &lt;code&gt;allowed_models&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You know exactly which model you want&lt;/td&gt;
&lt;td&gt;Pin &lt;code&gt;model_name&lt;/code&gt;, leave provider unset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You know the model and the provider you want&lt;/td&gt;
&lt;td&gt;Pin &lt;code&gt;model_name&lt;/code&gt; plus &lt;code&gt;openrouter.providers&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provider choice is a hard requirement&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;providers&lt;/code&gt; with &lt;code&gt;allow_fallbacks: false&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These are per request settings, not account level settings. Different endpoints in the same application can make different choices.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do you know which model actually ran?
&lt;/h2&gt;

&lt;p&gt;The response tells you. Backboard returns the provider and model that handled the request alongside token counts, so automatic selection does not become a visibility gap. You can log what ran, attribute cost to it, and audit routing behavior after the fact.&lt;/p&gt;

&lt;p&gt;That is the practical objection to automatic routing, and it is the reason the response carries the answer rather than leaving you to infer it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where can you see which providers serve a given model?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Backboard Model Library&lt;/strong&gt; now surfaces provider options for OpenRouter models, alongside pricing, context limits, uptime, and other model information.&lt;/p&gt;

&lt;p&gt;Browse it here: &lt;a href="https://app.backboard.io/dashboard/model-library" rel="noopener noreferrer"&gt;https://app.backboard.io/dashboard/model-library&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check the library before you hardcode a provider name. Provider availability for a given model changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What do you need to use this?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Backboard API key from &lt;a href="https://app.backboard.io" rel="noopener noreferrer"&gt;https://app.backboard.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;llm_provider&lt;/code&gt; set to &lt;code&gt;openrouter&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Backboard API, or the Python or TypeScript SDK at &lt;strong&gt;v1.5.16 or later&lt;/strong&gt;
Backboard's free tier includes $5 in memory credits and requires no credit card. Inference is billed separately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full parameter reference: &lt;a href="https://docs.backboard.io/concepts/messages" rel="noopener noreferrer"&gt;https://docs.backboard.io/concepts/messages&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is &lt;code&gt;openrouter/auto&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;
It is a model identifier that hands model selection to OpenRouter. Instead of naming a specific model, you name &lt;code&gt;openrouter/auto&lt;/code&gt;, and OpenRouter classifies the prompt and selects a model for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does automatic model selection add a fee?&lt;/strong&gt;&lt;br&gt;
No. You pay the standard rate of the model that gets selected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I limit automatic selection to certain models?&lt;/strong&gt;&lt;br&gt;
Yes. Use &lt;code&gt;allowed_models&lt;/code&gt; to restrict the candidate set, &lt;code&gt;excluded_models&lt;/code&gt; to remove specific models, and &lt;code&gt;cost_tier&lt;/code&gt; to cap price, on a scale from &lt;code&gt;low&lt;/code&gt; to &lt;code&gt;max&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I choose which provider serves a model on OpenRouter?&lt;/strong&gt;&lt;br&gt;
Yes. Pass a &lt;code&gt;providers&lt;/code&gt; array inside the &lt;code&gt;openrouter&lt;/code&gt; object in your Backboard request body.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does provider selection work with automatic model selection?&lt;/strong&gt;&lt;br&gt;
Provider selection applies to a model you have named. If you delegate model choice to &lt;code&gt;openrouter/auto&lt;/code&gt;, you are also delegating the provider that serves it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;allow_fallbacks&lt;/code&gt; do?&lt;/strong&gt;&lt;br&gt;
With &lt;code&gt;allow_fallbacks: true&lt;/code&gt;, a request can move to another provider serving the same model when your selected provider is unavailable. With it off, the provider choice is strict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which SDK versions support this?&lt;/strong&gt;&lt;br&gt;
Python and TypeScript SDK v1.5.16 and later, plus the Backboard API directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I find out which model handled my request?&lt;/strong&gt;&lt;br&gt;
The API response reports the provider and model that ran, so automatic selection stays auditable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;model_name: "openrouter/auto"&lt;/code&gt; delegates model choice to OpenRouter at no extra fee.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allowed_models&lt;/code&gt;, &lt;code&gt;excluded_models&lt;/code&gt;, and &lt;code&gt;cost_tier&lt;/code&gt; keep that delegation inside boundaries you set.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;openrouter.providers&lt;/code&gt; picks who serves a named model, and &lt;code&gt;allow_fallbacks&lt;/code&gt; decides whether that pick is a preference or a rule.&lt;/li&gt;
&lt;li&gt;The response reports what actually ran.&lt;/li&gt;
&lt;li&gt;Available now in the Backboard API and in the Python and TypeScript SDKs from v1.5.16.
Choose the model. Choose who runs it. Backboard handles the rest.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
