<?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: SPOE</title>
    <description>The latest articles on DEV Community by SPOE (@spoe).</description>
    <link>https://dev.to/spoe</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%2F4174412%2Fb4ea6155-9191-478a-9a96-08f2992bb44a.png</url>
      <title>DEV Community: SPOE</title>
      <link>https://dev.to/spoe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spoe"/>
    <language>en</language>
    <item>
      <title>Every change our AI app builder makes gets a second model’s review. A timeout is never a pass.</title>
      <dc:creator>SPOE</dc:creator>
      <pubDate>Sat, 10 Oct 2026 10:13:58 +0000</pubDate>
      <link>https://dev.to/spoe/every-change-our-ai-app-builder-makes-gets-a-second-models-review-a-timeout-is-never-a-pass-17na</link>
      <guid>https://dev.to/spoe/every-change-our-ai-app-builder-makes-gets-a-second-models-review-a-timeout-is-never-a-pass-17na</guid>
      <description>&lt;p&gt;I'm building SPOE, an AI app builder. You describe an app, a model writes it into a real Next.js, Fastify and Postgres project, and you can export the whole thing. &lt;a href="https://dev.to/spoe/we-sign-every-export-our-ai-app-builder-produces-heres-how-it-works-33ae"&gt;Last time&lt;/a&gt; I wrote about how every export is signed. This post is about the other half: nothing the builder writes reaches your project until a second model has read it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a second model, and why a different family
&lt;/h2&gt;

&lt;p&gt;A model reviewing its own output tends to like it. Two sizes of the same model family share training data, so they tend to share blind spots too. So the rule is that the reviewer must come from a different model family than the writer.&lt;/p&gt;

&lt;p&gt;That rule lives in code, not in a doc. The server reads the family off each model's id (Qwen, GLM, Llama, DeepSeek, Mistral and so on). If it can't tell, the operator has to state it. If the writer and the reviewer turn out to be the same family, the server refuses to start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`Reviewer and generator are both "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" family. The security review must use a different model family.`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you pick your own model for building, the reviewer is chosen from a different family than that one too. Both run on Venice's private, zero-retention inference.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reviewer sees
&lt;/h2&gt;

&lt;p&gt;It gets two things: the original request and the proposed diff. Its instructions open with "You are a security reviewer. You did not write this code."&lt;/p&gt;

&lt;p&gt;It looks for, roughly in this order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical:&lt;/strong&gt; injection, auth that can be bypassed, secrets in code, arbitrary file access, one user reaching another user's data. Also any import of an SPOE package, because the export has to run without us.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High:&lt;/strong&gt; missing validation at the edges, weak crypto or password storage, SSRF, path traversal, XSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; missing rate limits on auth, error messages that leak, insecure defaults.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It answers in JSON at temperature 0: a verdict, and findings that each name a file, a line, the problem and the fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't trust the model's own summary
&lt;/h2&gt;

&lt;p&gt;A model will happily list a critical finding and then write &lt;code&gt;"verdict": "pass"&lt;/code&gt; underneath it. So the verdict is worked out again on our side, from the findings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verdict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;findings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;sev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;verdict&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pass&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;findings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;verdict&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A critical finding blocks the change, whatever the reviewer wrote. A blocked change can't be approved at all. You regenerate, and the findings go back to the writer word for word as a checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  A timeout is never a pass
&lt;/h2&gt;

&lt;p&gt;This is the rule I care about most. When a review errors, times out or returns something that doesn't parse, the easy move is to let the change through. SPOE doesn't. A network or provider hiccup gets one retry. After that, the change comes back marked as not reviewed, with a note in plain words saying exactly that. Approving it takes an explicit "I know this is unreviewed", and that approval goes into the audit log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fast, without skipping the check
&lt;/h2&gt;

&lt;p&gt;At first, every change waited for a human in a diff view. Safe, and slow. Now, with auto-apply on (the default), a change the review passes goes in by itself, as a version you can undo in one click.&lt;/p&gt;

&lt;p&gt;Four kinds of change never apply themselves: a blocked one, an unreviewed one, one with a high or critical finding, and one whose files you edited by hand since it was written. Those wait in the diff view for you. A manual edit is never silently overwritten.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it falls short
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A second model is not a security audit. It catches common, obvious mistakes. It will miss subtle logic bugs, and it can be wrong in both directions.&lt;/li&gt;
&lt;li&gt;It reads the diff and the request, not the whole running system.&lt;/li&gt;
&lt;li&gt;Calibration never ends. A reviewer that calls everything critical gets ignored, so its instructions spell out what critical means: a human must not merge this, full stop. A missing rate limit is not that.&lt;/li&gt;
&lt;li&gt;Two families can still share blind spots. Different beats same. It is not a guarantee.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it, and tell me where it breaks
&lt;/h2&gt;

&lt;p&gt;SPOE is at &lt;a href="https://spoe.ai/?ref=devto" rel="noopener noreferrer"&gt;spoe.ai&lt;/a&gt;. You get 50 free credits to start, a build costs roughly 10 to 30, and your first payment of any size unlocks export for good.&lt;/p&gt;

&lt;p&gt;I'd like to hear where you think this review would fail. What would you want it to catch that it doesn't?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>We sign every export our AI app builder produces. Here's how it works</title>
      <dc:creator>SPOE</dc:creator>
      <pubDate>Sat, 10 Oct 2026 01:49:26 +0000</pubDate>
      <link>https://dev.to/spoe/we-sign-every-export-our-ai-app-builder-produces-heres-how-it-works-33ae</link>
      <guid>https://dev.to/spoe/we-sign-every-export-our-ai-app-builder-produces-heres-how-it-works-33ae</guid>
      <description>&lt;p&gt;I'm building SPOE, an AI app builder. Every tool in this space says "you own your code". I wanted to be able to prove it, so every export SPOE produces is signed. This is how that works, in enough detail that you can poke holes in it.&lt;/p&gt;

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

&lt;p&gt;When an AI writes your app, two questions follow the code around. Is this exactly what I was shown? And does it quietly depend on the tool that made it? A ZIP answers neither.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in an export
&lt;/h2&gt;

&lt;p&gt;Three files ride along with every project: &lt;code&gt;PROVENANCE.json&lt;/code&gt;, &lt;code&gt;PROVENANCE.sig&lt;/code&gt; and &lt;code&gt;verify-provenance.mjs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PROVENANCE.json&lt;/code&gt; lists every file with its SHA-256 and size, a hash over the whole tree, which models wrote and reviewed the changes (never the prompts), and the signer's public key:&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;"spoe_provenance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"project"&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;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tint-booker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"stack"&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;"frontend"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nextjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"backend"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"database"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&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;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&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;"files"&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;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"web/app/page.tsx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sha256"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9f2c…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"bytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1834&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;"tree_sha256"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"41ad…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"generator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reviewer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signer"&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;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ed25519"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"key_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c85280961cc26721"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"public_key_pem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-----BEGIN PUBLIC KEY-----…"&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;The signature in &lt;code&gt;PROVENANCE.sig&lt;/code&gt; is Ed25519 over a canonical form of that JSON: keys sorted recursively, no whitespace. The tree hash is SHA-256 over the sorted lines &lt;code&gt;path\0sha256\n&lt;/code&gt;, so the order files happen to be zipped in never matters. The key id is the first 16 hex characters of the SHA-256 of the public key's DER encoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying it
&lt;/h2&gt;

&lt;p&gt;The verifier is about 40 lines of plain Node 18+, with no packages and no network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node verify-provenance.mjs
OK   signature valid (key_id c85280961cc26721)
OK   30 files match manifest
VERIFIED - exported 2026-10-09T01:24:13Z from project tint-booker v2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It checks that the key id matches the embedded key, that the signature is valid, that every listed file is on disk with the right hash, and the tree hash. It exits 1 if anything is off.&lt;/p&gt;

&lt;p&gt;A valid signature only tells you the files match a key. To know who signed it, compare the key id with the keys spoe.ai publishes at &lt;a href="https://spoe.ai/api/signing-keys" rel="noopener noreferrer"&gt;spoe.ai/api/signing-keys&lt;/a&gt;. The page at &lt;a href="https://spoe.ai/verify?ref=devto" rel="noopener noreferrer"&gt;spoe.ai/verify&lt;/a&gt; does all of this in your browser without uploading the ZIP, and also lists any file in the ZIP that the manifest doesn't know about. The offline script now does that same check too.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Runs without us" is a test, not a promise
&lt;/h2&gt;

&lt;p&gt;Before an export is signed, a lint refuses it if anything ties it back to SPOE: an import of an SPOE package, a dependency on one, code reading &lt;code&gt;SPOE_*&lt;/code&gt; environment variables, a call to SPOE's API, or one of our internal folders. No warnings, no override.&lt;/p&gt;

&lt;p&gt;And CI does the whole thing on every commit: export the scaffold, unzip it into an empty directory, verify the signature, &lt;code&gt;docker compose up&lt;/code&gt;, hit the health check. If that fails, nothing ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other half: a second model
&lt;/h2&gt;

&lt;p&gt;Every change the builder makes is reviewed by a second model from a different model family before it lands. A critical finding blocks the change whatever the reviewer's own verdict says, and a review that times out or errors is never treated as a pass: it waits for a human.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't prove
&lt;/h2&gt;

&lt;p&gt;A signature proves integrity and origin, not quality. It can't tell you the code is free of bugs or safe to run; the review and your own eyes are for that. It also says nothing about the prompts, which are deliberately left out of the manifest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it, and tell me what's wrong with it
&lt;/h2&gt;

&lt;p&gt;SPOE is at &lt;a href="https://spoe.ai/?ref=devto" rel="noopener noreferrer"&gt;spoe.ai&lt;/a&gt;. It's free to start (50 credits on sign-up and a daily top-up), runs on Venice's private models, and your first payment of any size unlocks export for good.&lt;/p&gt;

&lt;p&gt;I'd especially like critique of the manifest format and the verifier. What would you need to see before you trusted an export from a tool like this?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>javascript</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
